My Project
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.5
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30/****************************************************************************\
31 * Note on documentation: The source files contain links to the online *
32 * documentation of the public API at https://json.nlohmann.me. This URL *
33 * contains the most recent documentation and should also be applicable to *
34 * previous versions; documentation for deprecated functions is not *
35 * removed, but marked deprecated. See "Generate documentation" section in *
36 * file docs/README.md. *
37\****************************************************************************/
38
39#ifndef INCLUDE_NLOHMANN_JSON_HPP_
40#define INCLUDE_NLOHMANN_JSON_HPP_
41
42#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
43 #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
44 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
45 #warning "Already included a different version of the library!"
46 #endif
47 #endif
48#endif
49
50#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
51#define NLOHMANN_JSON_VERSION_MINOR 10 // NOLINT(modernize-macro-to-enum)
52#define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
53
54#include <algorithm> // all_of, find, for_each
55#include <cstddef> // nullptr_t, ptrdiff_t, size_t
56#include <functional> // hash, less
57#include <initializer_list> // initializer_list
58#ifndef JSON_NO_IO
59 #include <iosfwd> // istream, ostream
60#endif // JSON_NO_IO
61#include <iterator> // random_access_iterator_tag
62#include <memory> // unique_ptr
63#include <numeric> // accumulate
64#include <string> // string, stoi, to_string
65#include <utility> // declval, forward, move, pair, swap
66#include <vector> // vector
67
68// #include <nlohmann/adl_serializer.hpp>
69
70
71#include <type_traits>
72#include <utility>
73
74// #include <nlohmann/detail/conversions/from_json.hpp>
75
76
77#include <algorithm> // transform
78#include <array> // array
79#include <forward_list> // forward_list
80#include <iterator> // inserter, front_inserter, end
81#include <map> // map
82#include <string> // string
83#include <tuple> // tuple, make_tuple
84#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
85#include <unordered_map> // unordered_map
86#include <utility> // pair, declval
87#include <valarray> // valarray
88
89// #include <nlohmann/detail/exceptions.hpp>
90
91
92#include <cstddef> // nullptr_t
93#include <exception> // exception
94#include <stdexcept> // runtime_error
95#include <string> // to_string
96#include <vector> // vector
97
98// #include <nlohmann/detail/value_t.hpp>
99
100
101#include <array> // array
102#include <cstddef> // size_t
103#include <cstdint> // uint8_t
104#include <string> // string
105
106namespace nlohmann
107{
108namespace detail
109{
111// JSON type enumeration //
113
138enum class value_t : std::uint8_t
139{
140 null,
141 object,
142 array,
143 string,
144 boolean,
148 binary,
149 discarded
150};
151
165inline bool operator<(const value_t lhs, const value_t rhs) noexcept
166{
167 static constexpr std::array<std::uint8_t, 9> order = {{
168 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
169 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
170 6 /* binary */
171 }
172 };
173
174 const auto l_index = static_cast<std::size_t>(lhs);
175 const auto r_index = static_cast<std::size_t>(rhs);
176 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
177}
178} // namespace detail
179} // namespace nlohmann
180
181// #include <nlohmann/detail/string_escape.hpp>
182
183
184// #include <nlohmann/detail/macro_scope.hpp>
185
186
187#include <utility> // declval, pair
188// #include <nlohmann/thirdparty/hedley/hedley.hpp>
189
190
191/* Hedley - https://nemequ.github.io/hedley
192 * Created by Evan Nemerson <evan@nemerson.com>
193 *
194 * To the extent possible under law, the author(s) have dedicated all
195 * copyright and related and neighboring rights to this software to
196 * the public domain worldwide. This software is distributed without
197 * any warranty.
198 *
199 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
200 * SPDX-License-Identifier: CC0-1.0
201 */
202
203#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
204#if defined(JSON_HEDLEY_VERSION)
205 #undef JSON_HEDLEY_VERSION
206#endif
207#define JSON_HEDLEY_VERSION 15
208
209#if defined(JSON_HEDLEY_STRINGIFY_EX)
210 #undef JSON_HEDLEY_STRINGIFY_EX
211#endif
212#define JSON_HEDLEY_STRINGIFY_EX(x) #x
213
214#if defined(JSON_HEDLEY_STRINGIFY)
215 #undef JSON_HEDLEY_STRINGIFY
216#endif
217#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
218
219#if defined(JSON_HEDLEY_CONCAT_EX)
220 #undef JSON_HEDLEY_CONCAT_EX
221#endif
222#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
223
224#if defined(JSON_HEDLEY_CONCAT)
225 #undef JSON_HEDLEY_CONCAT
226#endif
227#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
228
229#if defined(JSON_HEDLEY_CONCAT3_EX)
230 #undef JSON_HEDLEY_CONCAT3_EX
231#endif
232#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
233
234#if defined(JSON_HEDLEY_CONCAT3)
235 #undef JSON_HEDLEY_CONCAT3
236#endif
237#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
238
239#if defined(JSON_HEDLEY_VERSION_ENCODE)
240 #undef JSON_HEDLEY_VERSION_ENCODE
241#endif
242#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
243
244#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
245 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
246#endif
247#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
248
249#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
250 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
251#endif
252#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
253
254#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
255 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
256#endif
257#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
258
259#if defined(JSON_HEDLEY_GNUC_VERSION)
260 #undef JSON_HEDLEY_GNUC_VERSION
261#endif
262#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
263 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
264#elif defined(__GNUC__)
265 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
266#endif
267
268#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
269 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
270#endif
271#if defined(JSON_HEDLEY_GNUC_VERSION)
272 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
273#else
274 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
275#endif
276
277#if defined(JSON_HEDLEY_MSVC_VERSION)
278 #undef JSON_HEDLEY_MSVC_VERSION
279#endif
280#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
281 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
282#elif defined(_MSC_FULL_VER) && !defined(__ICL)
283 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
284#elif defined(_MSC_VER) && !defined(__ICL)
285 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
286#endif
287
288#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
289 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
290#endif
291#if !defined(JSON_HEDLEY_MSVC_VERSION)
292 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
293#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
294 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
295#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
296 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
297#else
298 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
299#endif
300
301#if defined(JSON_HEDLEY_INTEL_VERSION)
302 #undef JSON_HEDLEY_INTEL_VERSION
303#endif
304#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
305 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
306#elif defined(__INTEL_COMPILER) && !defined(__ICL)
307 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
308#endif
309
310#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
311 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
312#endif
313#if defined(JSON_HEDLEY_INTEL_VERSION)
314 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
315#else
316 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
317#endif
318
319#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
320 #undef JSON_HEDLEY_INTEL_CL_VERSION
321#endif
322#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
323 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
324#endif
325
326#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
327 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
328#endif
329#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
330 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
331#else
332 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
333#endif
334
335#if defined(JSON_HEDLEY_PGI_VERSION)
336 #undef JSON_HEDLEY_PGI_VERSION
337#endif
338#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
339 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
340#endif
341
342#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
343 #undef JSON_HEDLEY_PGI_VERSION_CHECK
344#endif
345#if defined(JSON_HEDLEY_PGI_VERSION)
346 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
347#else
348 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
349#endif
350
351#if defined(JSON_HEDLEY_SUNPRO_VERSION)
352 #undef JSON_HEDLEY_SUNPRO_VERSION
353#endif
354#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
355 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
356#elif defined(__SUNPRO_C)
357 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
358#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
359 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
360#elif defined(__SUNPRO_CC)
361 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
362#endif
363
364#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
365 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
366#endif
367#if defined(JSON_HEDLEY_SUNPRO_VERSION)
368 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
369#else
370 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
371#endif
372
373#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
374 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
375#endif
376#if defined(__EMSCRIPTEN__)
377 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
378#endif
379
380#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
381 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
382#endif
383#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
384 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
385#else
386 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
387#endif
388
389#if defined(JSON_HEDLEY_ARM_VERSION)
390 #undef JSON_HEDLEY_ARM_VERSION
391#endif
392#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
393 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
394#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
395 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
396#endif
397
398#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
399 #undef JSON_HEDLEY_ARM_VERSION_CHECK
400#endif
401#if defined(JSON_HEDLEY_ARM_VERSION)
402 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
403#else
404 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
405#endif
406
407#if defined(JSON_HEDLEY_IBM_VERSION)
408 #undef JSON_HEDLEY_IBM_VERSION
409#endif
410#if defined(__ibmxl__)
411 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
412#elif defined(__xlC__) && defined(__xlC_ver__)
413 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
414#elif defined(__xlC__)
415 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
416#endif
417
418#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
419 #undef JSON_HEDLEY_IBM_VERSION_CHECK
420#endif
421#if defined(JSON_HEDLEY_IBM_VERSION)
422 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
423#else
424 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
425#endif
426
427#if defined(JSON_HEDLEY_TI_VERSION)
428 #undef JSON_HEDLEY_TI_VERSION
429#endif
430#if \
431 defined(__TI_COMPILER_VERSION__) && \
432 ( \
433 defined(__TMS470__) || defined(__TI_ARM__) || \
434 defined(__MSP430__) || \
435 defined(__TMS320C2000__) \
436 )
437#if (__TI_COMPILER_VERSION__ >= 16000000)
438 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439#endif
440#endif
441
442#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
443 #undef JSON_HEDLEY_TI_VERSION_CHECK
444#endif
445#if defined(JSON_HEDLEY_TI_VERSION)
446 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
447#else
448 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
449#endif
450
451#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
452 #undef JSON_HEDLEY_TI_CL2000_VERSION
453#endif
454#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
455 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
456#endif
457
458#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
459 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
460#endif
461#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
462 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
463#else
464 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
465#endif
466
467#if defined(JSON_HEDLEY_TI_CL430_VERSION)
468 #undef JSON_HEDLEY_TI_CL430_VERSION
469#endif
470#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
471 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
472#endif
473
474#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
475 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
476#endif
477#if defined(JSON_HEDLEY_TI_CL430_VERSION)
478 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
479#else
480 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
481#endif
482
483#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
484 #undef JSON_HEDLEY_TI_ARMCL_VERSION
485#endif
486#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
487 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
488#endif
489
490#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
491 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
492#endif
493#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
494 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
495#else
496 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
497#endif
498
499#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
500 #undef JSON_HEDLEY_TI_CL6X_VERSION
501#endif
502#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
503 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
504#endif
505
506#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
507 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
508#endif
509#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
510 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
511#else
512 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
513#endif
514
515#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
516 #undef JSON_HEDLEY_TI_CL7X_VERSION
517#endif
518#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
519 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
520#endif
521
522#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
523 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
524#endif
525#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
526 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
527#else
528 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
529#endif
530
531#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
532 #undef JSON_HEDLEY_TI_CLPRU_VERSION
533#endif
534#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
535 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
536#endif
537
538#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
539 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
540#endif
541#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
542 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
543#else
544 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
545#endif
546
547#if defined(JSON_HEDLEY_CRAY_VERSION)
548 #undef JSON_HEDLEY_CRAY_VERSION
549#endif
550#if defined(_CRAYC)
551 #if defined(_RELEASE_PATCHLEVEL)
552 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
553 #else
554 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
555 #endif
556#endif
557
558#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
559 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
560#endif
561#if defined(JSON_HEDLEY_CRAY_VERSION)
562 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
563#else
564 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
565#endif
566
567#if defined(JSON_HEDLEY_IAR_VERSION)
568 #undef JSON_HEDLEY_IAR_VERSION
569#endif
570#if defined(__IAR_SYSTEMS_ICC__)
571 #if __VER__ > 1000
572 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
573 #else
574 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
575 #endif
576#endif
577
578#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
579 #undef JSON_HEDLEY_IAR_VERSION_CHECK
580#endif
581#if defined(JSON_HEDLEY_IAR_VERSION)
582 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
583#else
584 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
585#endif
586
587#if defined(JSON_HEDLEY_TINYC_VERSION)
588 #undef JSON_HEDLEY_TINYC_VERSION
589#endif
590#if defined(__TINYC__)
591 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
592#endif
593
594#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
595 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
596#endif
597#if defined(JSON_HEDLEY_TINYC_VERSION)
598 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
599#else
600 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
601#endif
602
603#if defined(JSON_HEDLEY_DMC_VERSION)
604 #undef JSON_HEDLEY_DMC_VERSION
605#endif
606#if defined(__DMC__)
607 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
608#endif
609
610#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
611 #undef JSON_HEDLEY_DMC_VERSION_CHECK
612#endif
613#if defined(JSON_HEDLEY_DMC_VERSION)
614 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
615#else
616 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
617#endif
618
619#if defined(JSON_HEDLEY_COMPCERT_VERSION)
620 #undef JSON_HEDLEY_COMPCERT_VERSION
621#endif
622#if defined(__COMPCERT_VERSION__)
623 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
624#endif
625
626#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
627 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
628#endif
629#if defined(JSON_HEDLEY_COMPCERT_VERSION)
630 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
631#else
632 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
633#endif
634
635#if defined(JSON_HEDLEY_PELLES_VERSION)
636 #undef JSON_HEDLEY_PELLES_VERSION
637#endif
638#if defined(__POCC__)
639 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
640#endif
641
642#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
643 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
644#endif
645#if defined(JSON_HEDLEY_PELLES_VERSION)
646 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
647#else
648 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
649#endif
650
651#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
652 #undef JSON_HEDLEY_MCST_LCC_VERSION
653#endif
654#if defined(__LCC__) && defined(__LCC_MINOR__)
655 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
656#endif
657
658#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
659 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
660#endif
661#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
662 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
663#else
664 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
665#endif
666
667#if defined(JSON_HEDLEY_GCC_VERSION)
668 #undef JSON_HEDLEY_GCC_VERSION
669#endif
670#if \
671 defined(JSON_HEDLEY_GNUC_VERSION) && \
672 !defined(__clang__) && \
673 !defined(JSON_HEDLEY_INTEL_VERSION) && \
674 !defined(JSON_HEDLEY_PGI_VERSION) && \
675 !defined(JSON_HEDLEY_ARM_VERSION) && \
676 !defined(JSON_HEDLEY_CRAY_VERSION) && \
677 !defined(JSON_HEDLEY_TI_VERSION) && \
678 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
679 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
680 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
681 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
682 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
683 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
684 !defined(__COMPCERT__) && \
685 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
686 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
687#endif
688
689#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
690 #undef JSON_HEDLEY_GCC_VERSION_CHECK
691#endif
692#if defined(JSON_HEDLEY_GCC_VERSION)
693 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
694#else
695 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
696#endif
697
698#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
699 #undef JSON_HEDLEY_HAS_ATTRIBUTE
700#endif
701#if \
702 defined(__has_attribute) && \
703 ( \
704 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
705 )
706# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
707#else
708# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
709#endif
710
711#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
712 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
713#endif
714#if defined(__has_attribute)
715 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
716#else
717 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
718#endif
719
720#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
721 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
722#endif
723#if defined(__has_attribute)
724 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
725#else
726 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
727#endif
728
729#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
730 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
731#endif
732#if \
733 defined(__has_cpp_attribute) && \
734 defined(__cplusplus) && \
735 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
736 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
737#else
738 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
739#endif
740
741#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
742 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
743#endif
744#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
745 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
746#elif \
747 !defined(JSON_HEDLEY_PGI_VERSION) && \
748 !defined(JSON_HEDLEY_IAR_VERSION) && \
749 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
750 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
751 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
752#else
753 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
754#endif
755
756#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
757 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
758#endif
759#if defined(__has_cpp_attribute) && defined(__cplusplus)
760 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
761#else
762 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
763#endif
764
765#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
766 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
767#endif
768#if defined(__has_cpp_attribute) && defined(__cplusplus)
769 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
770#else
771 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
772#endif
773
774#if defined(JSON_HEDLEY_HAS_BUILTIN)
775 #undef JSON_HEDLEY_HAS_BUILTIN
776#endif
777#if defined(__has_builtin)
778 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
779#else
780 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
781#endif
782
783#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
784 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
785#endif
786#if defined(__has_builtin)
787 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
788#else
789 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
790#endif
791
792#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
793 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
794#endif
795#if defined(__has_builtin)
796 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
797#else
798 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
799#endif
800
801#if defined(JSON_HEDLEY_HAS_FEATURE)
802 #undef JSON_HEDLEY_HAS_FEATURE
803#endif
804#if defined(__has_feature)
805 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
806#else
807 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
808#endif
809
810#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
811 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
812#endif
813#if defined(__has_feature)
814 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
815#else
816 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
817#endif
818
819#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
820 #undef JSON_HEDLEY_GCC_HAS_FEATURE
821#endif
822#if defined(__has_feature)
823 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
824#else
825 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
826#endif
827
828#if defined(JSON_HEDLEY_HAS_EXTENSION)
829 #undef JSON_HEDLEY_HAS_EXTENSION
830#endif
831#if defined(__has_extension)
832 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
833#else
834 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
835#endif
836
837#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
838 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
839#endif
840#if defined(__has_extension)
841 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
842#else
843 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
844#endif
845
846#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
847 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
848#endif
849#if defined(__has_extension)
850 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
851#else
852 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
853#endif
854
855#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
856 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
857#endif
858#if defined(__has_declspec_attribute)
859 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
860#else
861 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
862#endif
863
864#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
865 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
866#endif
867#if defined(__has_declspec_attribute)
868 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
869#else
870 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
871#endif
872
873#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
874 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
875#endif
876#if defined(__has_declspec_attribute)
877 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
878#else
879 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
880#endif
881
882#if defined(JSON_HEDLEY_HAS_WARNING)
883 #undef JSON_HEDLEY_HAS_WARNING
884#endif
885#if defined(__has_warning)
886 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
887#else
888 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
889#endif
890
891#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
892 #undef JSON_HEDLEY_GNUC_HAS_WARNING
893#endif
894#if defined(__has_warning)
895 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
896#else
897 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
898#endif
899
900#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
901 #undef JSON_HEDLEY_GCC_HAS_WARNING
902#endif
903#if defined(__has_warning)
904 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
905#else
906 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
907#endif
908
909#if \
910 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
911 defined(__clang__) || \
912 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
913 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
914 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
915 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
916 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
917 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
918 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
919 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
920 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
921 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
922 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
923 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
924 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
925 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
926 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
927 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
928 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
929#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
930 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
931#else
932 #define JSON_HEDLEY_PRAGMA(value)
933#endif
934
935#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
936 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
937#endif
938#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
939 #undef JSON_HEDLEY_DIAGNOSTIC_POP
940#endif
941#if defined(__clang__)
942 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
943 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
944#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
945 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
946 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
947#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
950#elif \
951 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
952 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
953 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
954 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
955#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
956 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
957 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
958#elif \
959 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
960 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
961 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
962 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
963 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
964 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
965 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
966 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
967#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
968 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
969 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
970#else
971 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
972 #define JSON_HEDLEY_DIAGNOSTIC_POP
973#endif
974
975/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
976 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
977#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
978 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
979#endif
980#if defined(__cplusplus)
981# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
982# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
983# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
984# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
985 JSON_HEDLEY_DIAGNOSTIC_PUSH \
986 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
987 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
988 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
989 xpr \
990 JSON_HEDLEY_DIAGNOSTIC_POP
991# else
992# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
993 JSON_HEDLEY_DIAGNOSTIC_PUSH \
994 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
995 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
996 xpr \
997 JSON_HEDLEY_DIAGNOSTIC_POP
998# endif
999# else
1000# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1001 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1002 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1003 xpr \
1004 JSON_HEDLEY_DIAGNOSTIC_POP
1005# endif
1006# endif
1007#endif
1008#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1009 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1010#endif
1011
1012#if defined(JSON_HEDLEY_CONST_CAST)
1013 #undef JSON_HEDLEY_CONST_CAST
1014#endif
1015#if defined(__cplusplus)
1016# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1017#elif \
1018 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1019 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1020 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1021# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1022 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1023 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1024 ((T) (expr)); \
1025 JSON_HEDLEY_DIAGNOSTIC_POP \
1026 }))
1027#else
1028# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1029#endif
1030
1031#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1032 #undef JSON_HEDLEY_REINTERPRET_CAST
1033#endif
1034#if defined(__cplusplus)
1035 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1036#else
1037 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1038#endif
1039
1040#if defined(JSON_HEDLEY_STATIC_CAST)
1041 #undef JSON_HEDLEY_STATIC_CAST
1042#endif
1043#if defined(__cplusplus)
1044 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1045#else
1046 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1047#endif
1048
1049#if defined(JSON_HEDLEY_CPP_CAST)
1050 #undef JSON_HEDLEY_CPP_CAST
1051#endif
1052#if defined(__cplusplus)
1053# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1054# define JSON_HEDLEY_CPP_CAST(T, expr) \
1055 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1056 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1057 ((T) (expr)) \
1058 JSON_HEDLEY_DIAGNOSTIC_POP
1059# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1060# define JSON_HEDLEY_CPP_CAST(T, expr) \
1061 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1062 _Pragma("diag_suppress=Pe137") \
1063 JSON_HEDLEY_DIAGNOSTIC_POP
1064# else
1065# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1066# endif
1067#else
1068# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1069#endif
1070
1071#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1072 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1073#endif
1074#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1075 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1076#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1077 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1078#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1079 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1080#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1081 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1082#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1083 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1084#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1086#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1088#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1090#elif \
1091 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1092 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1093 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1094 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1095 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1096 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1097 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1098 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1099 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1100 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1101 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1103#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1105#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1107#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1109#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1111#else
1112 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1113#endif
1114
1115#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1116 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1117#endif
1118#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1119 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1120#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1121 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1122#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1123 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1124#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1125 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1126#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1127 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1128#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1129 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1130#elif \
1131 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1132 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1133 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1134 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1136#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1138#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1140#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1142#else
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1144#endif
1145
1146#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1147 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1148#endif
1149#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1150 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1151#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1153#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1155#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1157#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1158 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1159#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1160 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1161#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1162 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1163#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1164 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1165#elif \
1166 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1167 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1168 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1170#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1171 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1172#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1173 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1174#else
1175 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1176#endif
1177
1178#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1179 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1180#endif
1181#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1183#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1185#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1186 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1187#else
1188 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1189#endif
1190
1191#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1192 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1193#endif
1194#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1195 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1196#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1197 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1198#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1199 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1200#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1201 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1202#else
1203 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1204#endif
1205
1206#if defined(JSON_HEDLEY_DEPRECATED)
1207 #undef JSON_HEDLEY_DEPRECATED
1208#endif
1209#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1210 #undef JSON_HEDLEY_DEPRECATED_FOR
1211#endif
1212#if \
1213 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1214 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1215 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1216 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1217#elif \
1218 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1219 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1220 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1221 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1222 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1223 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1224 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1225 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1226 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1227 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1228 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1229 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1230 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1231 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1232#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1233 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1234 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1235#elif \
1236 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1237 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1238 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1239 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1240 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1241 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1242 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1243 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1244 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1245 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1246 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1247 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1248 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1249 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1250 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1251 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1252 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1253 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1254#elif \
1255 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1256 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1257 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1258 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1259 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1260#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1261 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1262 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1263#else
1264 #define JSON_HEDLEY_DEPRECATED(since)
1265 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1266#endif
1267
1268#if defined(JSON_HEDLEY_UNAVAILABLE)
1269 #undef JSON_HEDLEY_UNAVAILABLE
1270#endif
1271#if \
1272 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1273 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1274 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1275 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1276 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1277#else
1278 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1279#endif
1280
1281#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1282 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1283#endif
1284#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1285 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1286#endif
1287#if \
1288 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1289 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1290 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1291 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1292 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1293 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1294 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1295 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1296 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1297 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1298 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1299 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1300 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1301 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1302 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1303 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1304 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1305 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1306 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1307#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1308 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1309 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1310#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1311 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1312 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1313#elif defined(_Check_return_) /* SAL */
1314 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1315 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1316#else
1317 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1318 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1319#endif
1320
1321#if defined(JSON_HEDLEY_SENTINEL)
1322 #undef JSON_HEDLEY_SENTINEL
1323#endif
1324#if \
1325 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1326 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1327 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1328 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1329 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1330 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1331#else
1332 #define JSON_HEDLEY_SENTINEL(position)
1333#endif
1334
1335#if defined(JSON_HEDLEY_NO_RETURN)
1336 #undef JSON_HEDLEY_NO_RETURN
1337#endif
1338#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1339 #define JSON_HEDLEY_NO_RETURN __noreturn
1340#elif \
1341 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1342 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1343 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1344#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1345 #define JSON_HEDLEY_NO_RETURN _Noreturn
1346#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1347 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1348#elif \
1349 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1350 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1351 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1352 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1353 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1354 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1355 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1356 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1357 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1358 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1359 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1360 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1361 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1362 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1363 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1364 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1365 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1366 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1367#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1368 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1369#elif \
1370 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1371 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1372 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1373#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1374 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1375#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1376 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1377#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1378 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1379#else
1380 #define JSON_HEDLEY_NO_RETURN
1381#endif
1382
1383#if defined(JSON_HEDLEY_NO_ESCAPE)
1384 #undef JSON_HEDLEY_NO_ESCAPE
1385#endif
1386#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1387 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1388#else
1389 #define JSON_HEDLEY_NO_ESCAPE
1390#endif
1391
1392#if defined(JSON_HEDLEY_UNREACHABLE)
1393 #undef JSON_HEDLEY_UNREACHABLE
1394#endif
1395#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1396 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1397#endif
1398#if defined(JSON_HEDLEY_ASSUME)
1399 #undef JSON_HEDLEY_ASSUME
1400#endif
1401#if \
1402 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1403 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1404 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1405 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1406#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1407 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1408#elif \
1409 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1410 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1411 #if defined(__cplusplus)
1412 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1413 #else
1414 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1415 #endif
1416#endif
1417#if \
1418 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1419 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1420 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1421 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1422 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1423 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1424 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1425 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1426#elif defined(JSON_HEDLEY_ASSUME)
1427 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1428#endif
1429#if !defined(JSON_HEDLEY_ASSUME)
1430 #if defined(JSON_HEDLEY_UNREACHABLE)
1431 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1432 #else
1433 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1434 #endif
1435#endif
1436#if defined(JSON_HEDLEY_UNREACHABLE)
1437 #if \
1438 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1439 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1440 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1441 #else
1442 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1443 #endif
1444#else
1445 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1446#endif
1447#if !defined(JSON_HEDLEY_UNREACHABLE)
1448 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1449#endif
1450
1452#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1453 #pragma clang diagnostic ignored "-Wpedantic"
1454#endif
1455#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1456 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1457#endif
1458#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1459 #if defined(__clang__)
1460 #pragma clang diagnostic ignored "-Wvariadic-macros"
1461 #elif defined(JSON_HEDLEY_GCC_VERSION)
1462 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1463 #endif
1464#endif
1465#if defined(JSON_HEDLEY_NON_NULL)
1466 #undef JSON_HEDLEY_NON_NULL
1467#endif
1468#if \
1469 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1470 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1471 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1472 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1473 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1474#else
1475 #define JSON_HEDLEY_NON_NULL(...)
1476#endif
1478
1479#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1480 #undef JSON_HEDLEY_PRINTF_FORMAT
1481#endif
1482#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1483 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1484#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1485 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1486#elif \
1487 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1488 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1489 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1490 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1491 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1492 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1493 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1494 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1495 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1496 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1497 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1498 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1499 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1500 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1501 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1502 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1503 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1504 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1505#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1506 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1507#else
1508 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1509#endif
1510
1511#if defined(JSON_HEDLEY_CONSTEXPR)
1512 #undef JSON_HEDLEY_CONSTEXPR
1513#endif
1514#if defined(__cplusplus)
1515 #if __cplusplus >= 201103L
1516 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1517 #endif
1518#endif
1519#if !defined(JSON_HEDLEY_CONSTEXPR)
1520 #define JSON_HEDLEY_CONSTEXPR
1521#endif
1522
1523#if defined(JSON_HEDLEY_PREDICT)
1524 #undef JSON_HEDLEY_PREDICT
1525#endif
1526#if defined(JSON_HEDLEY_LIKELY)
1527 #undef JSON_HEDLEY_LIKELY
1528#endif
1529#if defined(JSON_HEDLEY_UNLIKELY)
1530 #undef JSON_HEDLEY_UNLIKELY
1531#endif
1532#if defined(JSON_HEDLEY_UNPREDICTABLE)
1533 #undef JSON_HEDLEY_UNPREDICTABLE
1534#endif
1535#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1536 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1537#endif
1538#if \
1539 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1540 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1541 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1542# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1543# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1544# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1545# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1546# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1547#elif \
1548 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1549 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1550 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1551 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1552 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1553 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1554 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1555 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1556 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1557 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1558 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1559 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1560 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1561 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1562 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1563 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1564# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1565 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1566# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1567 (__extension__ ({ \
1568 double hedley_probability_ = (probability); \
1569 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1570 }))
1571# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1572 (__extension__ ({ \
1573 double hedley_probability_ = (probability); \
1574 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1575 }))
1576# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1577# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1578#else
1579# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1580# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1581# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1582# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1583# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1584#endif
1585#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1586 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1587#endif
1588
1589#if defined(JSON_HEDLEY_MALLOC)
1590 #undef JSON_HEDLEY_MALLOC
1591#endif
1592#if \
1593 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1594 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1595 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1596 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1597 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1598 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1599 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1600 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1601 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1602 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1603 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1604 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1605 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1606 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1607 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1608 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1609 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1610 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1611 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1612#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1613 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1614#elif \
1615 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1616 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1617 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1618#else
1619 #define JSON_HEDLEY_MALLOC
1620#endif
1621
1622#if defined(JSON_HEDLEY_PURE)
1623 #undef JSON_HEDLEY_PURE
1624#endif
1625#if \
1626 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1627 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1628 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1629 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1630 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1631 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1632 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1633 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1634 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1635 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1636 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1637 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1638 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1639 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1640 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1641 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1642 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1643 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1644 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1645# define JSON_HEDLEY_PURE __attribute__((__pure__))
1646#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1647# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1648#elif defined(__cplusplus) && \
1649 ( \
1650 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1651 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1652 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1653 )
1654# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1655#else
1656# define JSON_HEDLEY_PURE
1657#endif
1658
1659#if defined(JSON_HEDLEY_CONST)
1660 #undef JSON_HEDLEY_CONST
1661#endif
1662#if \
1663 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1664 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1665 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1666 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1667 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1668 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1669 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1670 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1671 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1672 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1673 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1674 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1675 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1676 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1677 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1678 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1679 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1680 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1681 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1682 #define JSON_HEDLEY_CONST __attribute__((__const__))
1683#elif \
1684 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1685 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1686#else
1687 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1688#endif
1689
1690#if defined(JSON_HEDLEY_RESTRICT)
1691 #undef JSON_HEDLEY_RESTRICT
1692#endif
1693#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1694 #define JSON_HEDLEY_RESTRICT restrict
1695#elif \
1696 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1697 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1698 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1699 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1700 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1701 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1702 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1703 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1704 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1705 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1706 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1707 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1708 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1709 defined(__clang__) || \
1710 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1711 #define JSON_HEDLEY_RESTRICT __restrict
1712#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1713 #define JSON_HEDLEY_RESTRICT _Restrict
1714#else
1715 #define JSON_HEDLEY_RESTRICT
1716#endif
1717
1718#if defined(JSON_HEDLEY_INLINE)
1719 #undef JSON_HEDLEY_INLINE
1720#endif
1721#if \
1722 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1723 (defined(__cplusplus) && (__cplusplus >= 199711L))
1724 #define JSON_HEDLEY_INLINE inline
1725#elif \
1726 defined(JSON_HEDLEY_GCC_VERSION) || \
1727 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1728 #define JSON_HEDLEY_INLINE __inline__
1729#elif \
1730 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1731 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1732 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1733 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1734 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1735 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1736 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1737 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1738 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1739 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1740 #define JSON_HEDLEY_INLINE __inline
1741#else
1742 #define JSON_HEDLEY_INLINE
1743#endif
1744
1745#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1746 #undef JSON_HEDLEY_ALWAYS_INLINE
1747#endif
1748#if \
1749 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1750 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1751 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1752 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1753 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1754 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1755 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1756 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1757 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1758 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1759 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1760 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1761 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1762 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1763 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1764 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1765 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1766 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1767 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1768# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1769#elif \
1770 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1771 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1772# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1773#elif defined(__cplusplus) && \
1774 ( \
1775 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1776 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1777 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1778 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1779 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1780 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1781 )
1782# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1783#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1784# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1785#else
1786# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1787#endif
1788
1789#if defined(JSON_HEDLEY_NEVER_INLINE)
1790 #undef JSON_HEDLEY_NEVER_INLINE
1791#endif
1792#if \
1793 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1794 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1795 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1796 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1797 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1798 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1799 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1800 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1801 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1802 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1803 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1804 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1805 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1806 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1807 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1808 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1809 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1810 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1811 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1812 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1813#elif \
1814 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1815 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1816 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1817#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1818 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1819#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1820 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1821#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1822 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1823#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1824 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1825#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1826 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1827#else
1828 #define JSON_HEDLEY_NEVER_INLINE
1829#endif
1830
1831#if defined(JSON_HEDLEY_PRIVATE)
1832 #undef JSON_HEDLEY_PRIVATE
1833#endif
1834#if defined(JSON_HEDLEY_PUBLIC)
1835 #undef JSON_HEDLEY_PUBLIC
1836#endif
1837#if defined(JSON_HEDLEY_IMPORT)
1838 #undef JSON_HEDLEY_IMPORT
1839#endif
1840#if defined(_WIN32) || defined(__CYGWIN__)
1841# define JSON_HEDLEY_PRIVATE
1842# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1843# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1844#else
1845# if \
1846 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1847 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1848 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1849 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1850 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1851 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1852 ( \
1853 defined(__TI_EABI__) && \
1854 ( \
1855 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1856 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1857 ) \
1858 ) || \
1859 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1861# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1862# else
1863# define JSON_HEDLEY_PRIVATE
1864# define JSON_HEDLEY_PUBLIC
1865# endif
1866# define JSON_HEDLEY_IMPORT extern
1867#endif
1868
1869#if defined(JSON_HEDLEY_NO_THROW)
1870 #undef JSON_HEDLEY_NO_THROW
1871#endif
1872#if \
1873 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1874 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1875 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1878#elif \
1879 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1880 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1881 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1882 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1883#else
1884 #define JSON_HEDLEY_NO_THROW
1885#endif
1886
1887#if defined(JSON_HEDLEY_FALL_THROUGH)
1888 #undef JSON_HEDLEY_FALL_THROUGH
1889#endif
1890#if \
1891 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1892 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1893 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1894 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1895#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1896 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1897#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1898 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1899#elif defined(__fallthrough) /* SAL */
1900 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1901#else
1902 #define JSON_HEDLEY_FALL_THROUGH
1903#endif
1904
1905#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1906 #undef JSON_HEDLEY_RETURNS_NON_NULL
1907#endif
1908#if \
1909 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1910 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1911 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1912 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1913#elif defined(_Ret_notnull_) /* SAL */
1914 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1915#else
1916 #define JSON_HEDLEY_RETURNS_NON_NULL
1917#endif
1918
1919#if defined(JSON_HEDLEY_ARRAY_PARAM)
1920 #undef JSON_HEDLEY_ARRAY_PARAM
1921#endif
1922#if \
1923 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1924 !defined(__STDC_NO_VLA__) && \
1925 !defined(__cplusplus) && \
1926 !defined(JSON_HEDLEY_PGI_VERSION) && \
1927 !defined(JSON_HEDLEY_TINYC_VERSION)
1928 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1929#else
1930 #define JSON_HEDLEY_ARRAY_PARAM(name)
1931#endif
1932
1933#if defined(JSON_HEDLEY_IS_CONSTANT)
1934 #undef JSON_HEDLEY_IS_CONSTANT
1935#endif
1936#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1937 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1938#endif
1939/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1940 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1941#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1942 #undef JSON_HEDLEY_IS_CONSTEXPR_
1943#endif
1944#if \
1945 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1946 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1947 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1948 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1949 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1950 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1951 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1952 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1953 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1954 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1955 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1956#endif
1957#if !defined(__cplusplus)
1958# if \
1959 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1960 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1961 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1962 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1963 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1964 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1965 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1966#if defined(__INTPTR_TYPE__)
1967 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1968#else
1969 #include <stdint.h>
1970 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1971#endif
1972# elif \
1973 ( \
1974 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1975 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1976 !defined(JSON_HEDLEY_PGI_VERSION) && \
1977 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1978 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1979 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1980 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1981 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1982 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1983#if defined(__INTPTR_TYPE__)
1984 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1985#else
1986 #include <stdint.h>
1987 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1988#endif
1989# elif \
1990 defined(JSON_HEDLEY_GCC_VERSION) || \
1991 defined(JSON_HEDLEY_INTEL_VERSION) || \
1992 defined(JSON_HEDLEY_TINYC_VERSION) || \
1993 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1994 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1995 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1996 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1997 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1998 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1999 defined(__clang__)
2000# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2001 sizeof(void) != \
2002 sizeof(*( \
2003 1 ? \
2004 ((void*) ((expr) * 0L) ) : \
2005((struct { char v[sizeof(void) * 2]; } *) 1) \
2006 ) \
2007 ) \
2008 )
2009# endif
2010#endif
2011#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2012 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2013 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2014 #endif
2015 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2016#else
2017 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2018 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2019 #endif
2020 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2021#endif
2022
2023#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2024 #undef JSON_HEDLEY_BEGIN_C_DECLS
2025#endif
2026#if defined(JSON_HEDLEY_END_C_DECLS)
2027 #undef JSON_HEDLEY_END_C_DECLS
2028#endif
2029#if defined(JSON_HEDLEY_C_DECL)
2030 #undef JSON_HEDLEY_C_DECL
2031#endif
2032#if defined(__cplusplus)
2033 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2034 #define JSON_HEDLEY_END_C_DECLS }
2035 #define JSON_HEDLEY_C_DECL extern "C"
2036#else
2037 #define JSON_HEDLEY_BEGIN_C_DECLS
2038 #define JSON_HEDLEY_END_C_DECLS
2039 #define JSON_HEDLEY_C_DECL
2040#endif
2041
2042#if defined(JSON_HEDLEY_STATIC_ASSERT)
2043 #undef JSON_HEDLEY_STATIC_ASSERT
2044#endif
2045#if \
2046 !defined(__cplusplus) && ( \
2047 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2048 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2049 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2050 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2051 defined(_Static_assert) \
2052 )
2053# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2054#elif \
2055 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2056 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2057 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2058# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2059#else
2060# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2061#endif
2062
2063#if defined(JSON_HEDLEY_NULL)
2064 #undef JSON_HEDLEY_NULL
2065#endif
2066#if defined(__cplusplus)
2067 #if __cplusplus >= 201103L
2068 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2069 #elif defined(NULL)
2070 #define JSON_HEDLEY_NULL NULL
2071 #else
2072 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2073 #endif
2074#elif defined(NULL)
2075 #define JSON_HEDLEY_NULL NULL
2076#else
2077 #define JSON_HEDLEY_NULL ((void*) 0)
2078#endif
2079
2080#if defined(JSON_HEDLEY_MESSAGE)
2081 #undef JSON_HEDLEY_MESSAGE
2082#endif
2083#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2084# define JSON_HEDLEY_MESSAGE(msg) \
2085 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2086 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2087 JSON_HEDLEY_PRAGMA(message msg) \
2088 JSON_HEDLEY_DIAGNOSTIC_POP
2089#elif \
2090 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2091 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2092# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2093#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2094# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2095#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2096# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2097#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2098# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2099#else
2100# define JSON_HEDLEY_MESSAGE(msg)
2101#endif
2102
2103#if defined(JSON_HEDLEY_WARNING)
2104 #undef JSON_HEDLEY_WARNING
2105#endif
2106#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2107# define JSON_HEDLEY_WARNING(msg) \
2108 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2109 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2110 JSON_HEDLEY_PRAGMA(clang warning msg) \
2111 JSON_HEDLEY_DIAGNOSTIC_POP
2112#elif \
2113 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2114 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2115 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2116# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2117#elif \
2118 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2119 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2120# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2121#else
2122# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2123#endif
2124
2125#if defined(JSON_HEDLEY_REQUIRE)
2126 #undef JSON_HEDLEY_REQUIRE
2127#endif
2128#if defined(JSON_HEDLEY_REQUIRE_MSG)
2129 #undef JSON_HEDLEY_REQUIRE_MSG
2130#endif
2131#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2132# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2133# define JSON_HEDLEY_REQUIRE(expr) \
2134 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2135 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2136 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2137 JSON_HEDLEY_DIAGNOSTIC_POP
2138# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2139 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2140 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2141 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2142 JSON_HEDLEY_DIAGNOSTIC_POP
2143# else
2144# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2145# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2146# endif
2147#else
2148# define JSON_HEDLEY_REQUIRE(expr)
2149# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2150#endif
2151
2152#if defined(JSON_HEDLEY_FLAGS)
2153 #undef JSON_HEDLEY_FLAGS
2154#endif
2155#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2156 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2157#else
2158 #define JSON_HEDLEY_FLAGS
2159#endif
2160
2161#if defined(JSON_HEDLEY_FLAGS_CAST)
2162 #undef JSON_HEDLEY_FLAGS_CAST
2163#endif
2164#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2165# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2166 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2167 _Pragma("warning(disable:188)") \
2168 ((T) (expr)); \
2169 JSON_HEDLEY_DIAGNOSTIC_POP \
2170 }))
2171#else
2172# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2173#endif
2174
2175#if defined(JSON_HEDLEY_EMPTY_BASES)
2176 #undef JSON_HEDLEY_EMPTY_BASES
2177#endif
2178#if \
2179 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2180 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2181 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2182#else
2183 #define JSON_HEDLEY_EMPTY_BASES
2184#endif
2185
2186/* Remaining macros are deprecated. */
2187
2188#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2189 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2190#endif
2191#if defined(__clang__)
2192 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2193#else
2194 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2195#endif
2196
2197#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2198 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2199#endif
2200#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2201
2202#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2203 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2204#endif
2205#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2206
2207#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2208 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2209#endif
2210#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2211
2212#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2213 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2214#endif
2215#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2216
2217#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2218 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2219#endif
2220#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2221
2222#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2223 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2224#endif
2225#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2226
2227#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2228 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2229#endif
2230#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2231
2232#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2233
2234// #include <nlohmann/detail/meta/detected.hpp>
2235
2236
2237#include <type_traits>
2238
2239// #include <nlohmann/detail/meta/void_t.hpp>
2240
2241
2242namespace nlohmann
2243{
2244namespace detail
2245{
2246template<typename ...Ts> struct make_void
2247{
2248 using type = void;
2249};
2250template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2251} // namespace detail
2252} // namespace nlohmann
2253
2254
2255// https://en.cppreference.com/w/cpp/experimental/is_detected
2256namespace nlohmann
2257{
2258namespace detail
2259{
2261{
2262 nonesuch() = delete;
2263 ~nonesuch() = delete;
2264 nonesuch(nonesuch const&) = delete;
2265 nonesuch(nonesuch const&&) = delete;
2266 void operator=(nonesuch const&) = delete;
2267 void operator=(nonesuch&&) = delete;
2268};
2269
2270template<class Default,
2271 class AlwaysVoid,
2272 template<class...> class Op,
2273 class... Args>
2275{
2276 using value_t = std::false_type;
2277 using type = Default;
2278};
2279
2280template<class Default, template<class...> class Op, class... Args>
2281struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2282{
2283 using value_t = std::true_type;
2284 using type = Op<Args...>;
2285};
2286
2287template<template<class...> class Op, class... Args>
2288using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2289
2290template<template<class...> class Op, class... Args>
2291struct is_detected_lazy : is_detected<Op, Args...> { };
2292
2293template<template<class...> class Op, class... Args>
2294using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2295
2296template<class Default, template<class...> class Op, class... Args>
2297using detected_or = detector<Default, void, Op, Args...>;
2298
2299template<class Default, template<class...> class Op, class... Args>
2300using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2301
2302template<class Expected, template<class...> class Op, class... Args>
2303using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2304
2305template<class To, template<class...> class Op, class... Args>
2307 std::is_convertible<detected_t<Op, Args...>, To>;
2308} // namespace detail
2309} // namespace nlohmann
2310
2311
2312// This file contains all internal macro definitions
2313// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2314
2315// exclude unsupported compilers
2316#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2317 #if defined(__clang__)
2318 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2319 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2320 #endif
2321 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2322 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2323 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2324 #endif
2325 #endif
2326#endif
2327
2328// C++ language standard detection
2329// if the user manually specified the used c++ version this is skipped
2330#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2331 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2332 #define JSON_HAS_CPP_20
2333 #define JSON_HAS_CPP_17
2334 #define JSON_HAS_CPP_14
2335 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2336 #define JSON_HAS_CPP_17
2337 #define JSON_HAS_CPP_14
2338 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2339 #define JSON_HAS_CPP_14
2340 #endif
2341 // the cpp 11 flag is always specified because it is the minimal required version
2342 #define JSON_HAS_CPP_11
2343#endif
2344
2345#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2346 #ifdef JSON_HAS_CPP_17
2347 #if defined(__cpp_lib_filesystem)
2348 #define JSON_HAS_FILESYSTEM 1
2349 #elif defined(__cpp_lib_experimental_filesystem)
2350 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2351 #elif !defined(__has_include)
2352 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2353 #elif __has_include(<filesystem>)
2354 #define JSON_HAS_FILESYSTEM 1
2355 #elif __has_include(<experimental/filesystem>)
2356 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2357 #endif
2358
2359 // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2360 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2361 #undef JSON_HAS_FILESYSTEM
2362 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2363 #endif
2364
2365 // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2366 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2367 #undef JSON_HAS_FILESYSTEM
2368 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2369 #endif
2370
2371 // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2372 #if defined(__clang_major__) && __clang_major__ < 7
2373 #undef JSON_HAS_FILESYSTEM
2374 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2375 #endif
2376
2377 // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2378 #if defined(_MSC_VER) && _MSC_VER < 1914
2379 #undef JSON_HAS_FILESYSTEM
2380 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2381 #endif
2382
2383 // no filesystem support before iOS 13
2384 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2385 #undef JSON_HAS_FILESYSTEM
2386 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2387 #endif
2388
2389 // no filesystem support before macOS Catalina
2390 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2391 #undef JSON_HAS_FILESYSTEM
2392 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2393 #endif
2394 #endif
2395#endif
2396
2397#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2398 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2399#endif
2400
2401#ifndef JSON_HAS_FILESYSTEM
2402 #define JSON_HAS_FILESYSTEM 0
2403#endif
2404
2405#ifndef JSON_HAS_THREE_WAY_COMPARISON
2406 #if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L \
2407 && defined(__cpp_impl_three_way_comparison)&& __cpp_impl_three_way_comparison >= 201907L
2408 #define JSON_HAS_THREE_WAY_COMPARISON 1
2409 #else
2410 #define JSON_HAS_THREE_WAY_COMPARISON 0
2411 #endif
2412#endif
2413
2414#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2415 #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2416#else
2417 #define JSON_NO_UNIQUE_ADDRESS
2418#endif
2419
2420// disable documentation warnings on clang
2421#if defined(__clang__)
2422 #pragma clang diagnostic push
2423 #pragma clang diagnostic ignored "-Wdocumentation"
2424 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2425#endif
2426
2427// allow disabling exceptions
2428#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2429 #define JSON_THROW(exception) throw exception
2430 #define JSON_TRY try
2431 #define JSON_CATCH(exception) catch(exception)
2432 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2433#else
2434 #include <cstdlib>
2435 #define JSON_THROW(exception) std::abort()
2436 #define JSON_TRY if(true)
2437 #define JSON_CATCH(exception) if(false)
2438 #define JSON_INTERNAL_CATCH(exception) if(false)
2439#endif
2440
2441// override exception macros
2442#if defined(JSON_THROW_USER)
2443 #undef JSON_THROW
2444 #define JSON_THROW JSON_THROW_USER
2445#endif
2446#if defined(JSON_TRY_USER)
2447 #undef JSON_TRY
2448 #define JSON_TRY JSON_TRY_USER
2449#endif
2450#if defined(JSON_CATCH_USER)
2451 #undef JSON_CATCH
2452 #define JSON_CATCH JSON_CATCH_USER
2453 #undef JSON_INTERNAL_CATCH
2454 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2455#endif
2456#if defined(JSON_INTERNAL_CATCH_USER)
2457 #undef JSON_INTERNAL_CATCH
2458 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2459#endif
2460
2461// allow overriding assert
2462#if !defined(JSON_ASSERT)
2463 #include <cassert> // assert
2464 #define JSON_ASSERT(x) assert(x)
2465#endif
2466
2467// allow to access some private functions (needed by the test suite)
2468#if defined(JSON_TESTS_PRIVATE)
2469 #define JSON_PRIVATE_UNLESS_TESTED public
2470#else
2471 #define JSON_PRIVATE_UNLESS_TESTED private
2472#endif
2473
2479#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2480 template<typename BasicJsonType> \
2481 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2482 { \
2483 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2484 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2485 auto it = std::find_if(std::begin(m), std::end(m), \
2486 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2487 { \
2488 return ej_pair.first == e; \
2489 }); \
2490 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2491 } \
2492 template<typename BasicJsonType> \
2493 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2494 { \
2495 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2496 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2497 auto it = std::find_if(std::begin(m), std::end(m), \
2498 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2499 { \
2500 return ej_pair.second == j; \
2501 }); \
2502 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2503 }
2504
2505// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2506// may be removed in the future once the class is split.
2507
2508#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2509 template<template<typename, typename, typename...> class ObjectType, \
2510 template<typename, typename...> class ArrayType, \
2511 class StringType, class BooleanType, class NumberIntegerType, \
2512 class NumberUnsignedType, class NumberFloatType, \
2513 template<typename> class AllocatorType, \
2514 template<typename, typename = void> class JSONSerializer, \
2515 class BinaryType>
2516
2517#define NLOHMANN_BASIC_JSON_TPL \
2518 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2519 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2520 AllocatorType, JSONSerializer, BinaryType>
2521
2522// Macros to simplify conversion from/to types
2523
2524#define NLOHMANN_JSON_EXPAND( x ) x
2525#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2526#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2527 NLOHMANN_JSON_PASTE64, \
2528 NLOHMANN_JSON_PASTE63, \
2529 NLOHMANN_JSON_PASTE62, \
2530 NLOHMANN_JSON_PASTE61, \
2531 NLOHMANN_JSON_PASTE60, \
2532 NLOHMANN_JSON_PASTE59, \
2533 NLOHMANN_JSON_PASTE58, \
2534 NLOHMANN_JSON_PASTE57, \
2535 NLOHMANN_JSON_PASTE56, \
2536 NLOHMANN_JSON_PASTE55, \
2537 NLOHMANN_JSON_PASTE54, \
2538 NLOHMANN_JSON_PASTE53, \
2539 NLOHMANN_JSON_PASTE52, \
2540 NLOHMANN_JSON_PASTE51, \
2541 NLOHMANN_JSON_PASTE50, \
2542 NLOHMANN_JSON_PASTE49, \
2543 NLOHMANN_JSON_PASTE48, \
2544 NLOHMANN_JSON_PASTE47, \
2545 NLOHMANN_JSON_PASTE46, \
2546 NLOHMANN_JSON_PASTE45, \
2547 NLOHMANN_JSON_PASTE44, \
2548 NLOHMANN_JSON_PASTE43, \
2549 NLOHMANN_JSON_PASTE42, \
2550 NLOHMANN_JSON_PASTE41, \
2551 NLOHMANN_JSON_PASTE40, \
2552 NLOHMANN_JSON_PASTE39, \
2553 NLOHMANN_JSON_PASTE38, \
2554 NLOHMANN_JSON_PASTE37, \
2555 NLOHMANN_JSON_PASTE36, \
2556 NLOHMANN_JSON_PASTE35, \
2557 NLOHMANN_JSON_PASTE34, \
2558 NLOHMANN_JSON_PASTE33, \
2559 NLOHMANN_JSON_PASTE32, \
2560 NLOHMANN_JSON_PASTE31, \
2561 NLOHMANN_JSON_PASTE30, \
2562 NLOHMANN_JSON_PASTE29, \
2563 NLOHMANN_JSON_PASTE28, \
2564 NLOHMANN_JSON_PASTE27, \
2565 NLOHMANN_JSON_PASTE26, \
2566 NLOHMANN_JSON_PASTE25, \
2567 NLOHMANN_JSON_PASTE24, \
2568 NLOHMANN_JSON_PASTE23, \
2569 NLOHMANN_JSON_PASTE22, \
2570 NLOHMANN_JSON_PASTE21, \
2571 NLOHMANN_JSON_PASTE20, \
2572 NLOHMANN_JSON_PASTE19, \
2573 NLOHMANN_JSON_PASTE18, \
2574 NLOHMANN_JSON_PASTE17, \
2575 NLOHMANN_JSON_PASTE16, \
2576 NLOHMANN_JSON_PASTE15, \
2577 NLOHMANN_JSON_PASTE14, \
2578 NLOHMANN_JSON_PASTE13, \
2579 NLOHMANN_JSON_PASTE12, \
2580 NLOHMANN_JSON_PASTE11, \
2581 NLOHMANN_JSON_PASTE10, \
2582 NLOHMANN_JSON_PASTE9, \
2583 NLOHMANN_JSON_PASTE8, \
2584 NLOHMANN_JSON_PASTE7, \
2585 NLOHMANN_JSON_PASTE6, \
2586 NLOHMANN_JSON_PASTE5, \
2587 NLOHMANN_JSON_PASTE4, \
2588 NLOHMANN_JSON_PASTE3, \
2589 NLOHMANN_JSON_PASTE2, \
2590 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2591#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2592#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2593#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2594#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2595#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2596#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2597#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2598#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2599#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2600#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2601#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2602#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2603#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2604#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2605#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2606#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2607#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2608#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2609#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2610#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2611#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2612#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2613#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2614#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2615#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2616#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2617#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2618#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2619#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2620#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2621#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2622#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2623#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2624#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2625#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2626#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2627#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2628#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2629#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2630#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2631#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2632#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2633#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2634#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2635#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2636#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2637#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2638#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2639#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2640#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2641#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2642#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2643#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2644#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2645#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2646#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2647#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2648#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2649#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2650#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2651#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2652#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2653#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2654
2655#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2656#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2657#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2658
2664#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2665 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2666 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2667
2668#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2669 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2670 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2671
2677#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2678 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2679 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2680
2681#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2682 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2683 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2684
2685
2686// inspired from https://stackoverflow.com/a/26745591
2687// allows to call any std function as if (e.g. with begin):
2688// using std::begin; begin(x);
2689//
2690// it allows using the detected idiom to retrieve the return type
2691// of such an expression
2692#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2693 namespace detail { \
2694 using std::std_name; \
2695 \
2696 template<typename... T> \
2697 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2698 } \
2699 \
2700 namespace detail2 { \
2701 struct std_name##_tag \
2702 { \
2703 }; \
2704 \
2705 template<typename... T> \
2706 std_name##_tag std_name(T&&...); \
2707 \
2708 template<typename... T> \
2709 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2710 \
2711 template<typename... T> \
2712 struct would_call_std_##std_name \
2713 { \
2714 static constexpr auto const value = ::nlohmann::detail:: \
2715 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2716 }; \
2717 } /* namespace detail2 */ \
2718 \
2719 template<typename... T> \
2720 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2721 { \
2722 }
2723
2724#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2725 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2726#endif
2727
2728#if JSON_USE_IMPLICIT_CONVERSIONS
2729 #define JSON_EXPLICIT
2730#else
2731 #define JSON_EXPLICIT explicit
2732#endif
2733
2734#ifndef JSON_DIAGNOSTICS
2735 #define JSON_DIAGNOSTICS 0
2736#endif
2737
2738
2739namespace nlohmann
2740{
2741namespace detail
2742{
2743
2757template<typename StringType>
2758inline void replace_substring(StringType& s, const StringType& f,
2759 const StringType& t)
2760{
2761 JSON_ASSERT(!f.empty());
2762 for (auto pos = s.find(f); // find first occurrence of f
2763 pos != StringType::npos; // make sure f was found
2764 s.replace(pos, f.size(), t), // replace with t, and
2765 pos = s.find(f, pos + t.size())) // find next occurrence of f
2766 {}
2767}
2768
2776template<typename StringType>
2777inline StringType escape(StringType s)
2778{
2779 replace_substring(s, StringType{"~"}, StringType{"~0"});
2780 replace_substring(s, StringType{"/"}, StringType{"~1"});
2781 return s;
2782}
2783
2791template<typename StringType>
2792static void unescape(StringType& s)
2793{
2794 replace_substring(s, StringType{"~1"}, StringType{"/"});
2795 replace_substring(s, StringType{"~0"}, StringType{"~"});
2796}
2797
2798} // namespace detail
2799} // namespace nlohmann
2800
2801// #include <nlohmann/detail/input/position_t.hpp>
2802
2803
2804#include <cstddef> // size_t
2805
2806namespace nlohmann
2807{
2808namespace detail
2809{
2812{
2814 std::size_t chars_read_total = 0;
2818 std::size_t lines_read = 0;
2819
2821 constexpr operator size_t() const
2822 {
2823 return chars_read_total;
2824 }
2825};
2826
2827} // namespace detail
2828} // namespace nlohmann
2829
2830// #include <nlohmann/detail/macro_scope.hpp>
2831
2832// #include <nlohmann/detail/meta/cpp_future.hpp>
2833
2834
2835#include <cstddef> // size_t
2836#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2837#include <utility> // index_sequence, make_index_sequence, index_sequence_for
2838
2839// #include <nlohmann/detail/macro_scope.hpp>
2840
2841
2842namespace nlohmann
2843{
2844namespace detail
2845{
2846
2847template<typename T>
2848using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2849
2850#ifdef JSON_HAS_CPP_14
2851
2852// the following utilities are natively available in C++14
2853using std::enable_if_t;
2857
2858#else
2859
2860// alias templates to reduce boilerplate
2861template<bool B, typename T = void>
2862using enable_if_t = typename std::enable_if<B, T>::type;
2863
2864// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
2865// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
2866
2868
2869// integer_sequence
2870//
2871// Class template representing a compile-time integer sequence. An instantiation
2872// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
2873// type through its template arguments (which is a common need when
2874// working with C++11 variadic templates). `absl::integer_sequence` is designed
2875// to be a drop-in replacement for C++14's `std::integer_sequence`.
2876//
2877// Example:
2878//
2879// template< class T, T... Ints >
2880// void user_function(integer_sequence<T, Ints...>);
2881//
2882// int main()
2883// {
2884// // user_function's `T` will be deduced to `int` and `Ints...`
2885// // will be deduced to `0, 1, 2, 3, 4`.
2886// user_function(make_integer_sequence<int, 5>());
2887// }
2888template <typename T, T... Ints>
2890{
2891 using value_type = T;
2892 static constexpr std::size_t size() noexcept
2893 {
2894 return sizeof...(Ints);
2895 }
2896};
2897
2898// index_sequence
2899//
2900// A helper template for an `integer_sequence` of `size_t`,
2901// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
2902// `std::index_sequence`.
2903template <size_t... Ints>
2904using index_sequence = integer_sequence<size_t, Ints...>;
2905
2906namespace utility_internal
2907{
2908
2909template <typename Seq, size_t SeqSize, size_t Rem>
2910struct Extend;
2911
2912// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
2913template <typename T, T... Ints, size_t SeqSize>
2914struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
2915{
2916 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
2917};
2918
2919template <typename T, T... Ints, size_t SeqSize>
2920struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
2921{
2922 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
2923};
2924
2925// Recursion helper for 'make_integer_sequence<T, N>'.
2926// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
2927template <typename T, size_t N>
2928struct Gen
2929{
2930 using type =
2931 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
2932};
2933
2934template <typename T>
2935struct Gen<T, 0>
2936{
2938};
2939
2940} // namespace utility_internal
2941
2942// Compile-time sequences of integers
2943
2944// make_integer_sequence
2945//
2946// This template alias is equivalent to
2947// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
2948// replacement for C++14's `std::make_integer_sequence`.
2949template <typename T, T N>
2951
2952// make_index_sequence
2953//
2954// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
2955// and is designed to be a drop-in replacement for C++14's
2956// `std::make_index_sequence`.
2957template <size_t N>
2959
2960// index_sequence_for
2961//
2962// Converts a typename pack into an index sequence of the same length, and
2963// is designed to be a drop-in replacement for C++14's
2964// `std::index_sequence_for()`
2965template <typename... Ts>
2967
2969
2970#endif
2971
2972// dispatch utility (taken from ranges-v3)
2973template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2974template<> struct priority_tag<0> {};
2975
2976// taken from ranges-v3
2977template<typename T>
2979{
2980 static constexpr T value{};
2981};
2982
2983#ifndef JSON_HAS_CPP_17
2984
2985 template<typename T>
2986 constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
2987
2988#endif
2989
2990} // namespace detail
2991} // namespace nlohmann
2992
2993// #include <nlohmann/detail/meta/type_traits.hpp>
2994
2995
2996#include <limits> // numeric_limits
2997#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2998#include <utility> // declval
2999#include <tuple> // tuple
3000
3001// #include <nlohmann/detail/macro_scope.hpp>
3002
3003
3004// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3005
3006
3007#include <iterator> // random_access_iterator_tag
3008
3009// #include <nlohmann/detail/meta/void_t.hpp>
3010
3011// #include <nlohmann/detail/meta/cpp_future.hpp>
3012
3013
3014namespace nlohmann
3015{
3016namespace detail
3017{
3018template<typename It, typename = void>
3020
3021template<typename It>
3023 It,
3024 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3025 typename It::reference, typename It::iterator_category >>
3026{
3027 using difference_type = typename It::difference_type;
3028 using value_type = typename It::value_type;
3029 using pointer = typename It::pointer;
3030 using reference = typename It::reference;
3031 using iterator_category = typename It::iterator_category;
3032};
3033
3034// This is required as some compilers implement std::iterator_traits in a way that
3035// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3036template<typename T, typename = void>
3038{
3039};
3040
3041template<typename T>
3042struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3043 : iterator_types<T>
3044{
3045};
3046
3047template<typename T>
3049{
3050 using iterator_category = std::random_access_iterator_tag;
3051 using value_type = T;
3052 using difference_type = ptrdiff_t;
3053 using pointer = T*;
3054 using reference = T&;
3055};
3056} // namespace detail
3057} // namespace nlohmann
3058
3059// #include <nlohmann/detail/meta/call_std/begin.hpp>
3060
3061
3062// #include <nlohmann/detail/macro_scope.hpp>
3063
3064
3065namespace nlohmann
3066{
3068} // namespace nlohmann
3069
3070// #include <nlohmann/detail/meta/call_std/end.hpp>
3071
3072
3073// #include <nlohmann/detail/macro_scope.hpp>
3074
3075
3076namespace nlohmann
3077{
3079} // namespace nlohmann
3080
3081// #include <nlohmann/detail/meta/cpp_future.hpp>
3082
3083// #include <nlohmann/detail/meta/detected.hpp>
3084
3085// #include <nlohmann/json_fwd.hpp>
3086#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3087#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3088
3089#include <cstdint> // int64_t, uint64_t
3090#include <map> // map
3091#include <memory> // allocator
3092#include <string> // string
3093#include <vector> // vector
3094
3100namespace nlohmann
3101{
3109template<typename T = void, typename SFINAE = void>
3110struct adl_serializer;
3111
3114template<template<typename U, typename V, typename... Args> class ObjectType =
3115 std::map,
3116 template<typename U, typename... Args> class ArrayType = std::vector,
3117 class StringType = std::string, class BooleanType = bool,
3118 class NumberIntegerType = std::int64_t,
3119 class NumberUnsignedType = std::uint64_t,
3120 class NumberFloatType = double,
3121 template<typename U> class AllocatorType = std::allocator,
3122 template<typename T, typename SFINAE = void> class JSONSerializer =
3123 adl_serializer,
3124 class BinaryType = std::vector<std::uint8_t>>
3125class basic_json;
3126
3129template<typename BasicJsonType>
3130class json_pointer;
3131
3137
3140template<class Key, class T, class IgnoredLess, class Allocator>
3141struct ordered_map;
3142
3146
3147} // namespace nlohmann
3148
3149#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3150
3151
3152namespace nlohmann
3153{
3162namespace detail
3163{
3165// helpers //
3167
3168// Note to maintainers:
3169//
3170// Every trait in this file expects a non CV-qualified type.
3171// The only exceptions are in the 'aliases for detected' section
3172// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3173//
3174// In this case, T has to be properly CV-qualified to constraint the function arguments
3175// (e.g. to_json(BasicJsonType&, const T&))
3176
3177template<typename> struct is_basic_json : std::false_type {};
3178
3180struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3181
3182// used by exceptions create() member functions
3183// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3184// false_type otherwise
3185template<typename BasicJsonContext>
3187 std::integral_constant < bool,
3188 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3189 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3190{};
3191
3193// json_ref helpers //
3195
3196template<typename>
3197class json_ref;
3198
3199template<typename>
3200struct is_json_ref : std::false_type {};
3201
3202template<typename T>
3203struct is_json_ref<json_ref<T>> : std::true_type {};
3204
3206// aliases for detected //
3208
3209template<typename T>
3210using mapped_type_t = typename T::mapped_type;
3211
3212template<typename T>
3213using key_type_t = typename T::key_type;
3214
3215template<typename T>
3216using value_type_t = typename T::value_type;
3217
3218template<typename T>
3219using difference_type_t = typename T::difference_type;
3220
3221template<typename T>
3222using pointer_t = typename T::pointer;
3223
3224template<typename T>
3225using reference_t = typename T::reference;
3226
3227template<typename T>
3228using iterator_category_t = typename T::iterator_category;
3229
3230template<typename T, typename... Args>
3231using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3232
3233template<typename T, typename... Args>
3234using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3235
3236template<typename T, typename U>
3237using get_template_function = decltype(std::declval<T>().template get<U>());
3238
3239// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3240template<typename BasicJsonType, typename T, typename = void>
3241struct has_from_json : std::false_type {};
3242
3243// trait checking if j.get<T> is valid
3244// use this trait instead of std::is_constructible or std::is_convertible,
3245// both rely on, or make use of implicit conversions, and thus fail when T
3246// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3247template <typename BasicJsonType, typename T>
3249{
3251};
3252
3253template<typename BasicJsonType, typename T>
3254struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3255{
3256 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3257
3258 static constexpr bool value =
3260 const BasicJsonType&, T&>::value;
3261};
3262
3263// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3264// this overload is used for non-default-constructible user-defined-types
3265template<typename BasicJsonType, typename T, typename = void>
3266struct has_non_default_from_json : std::false_type {};
3267
3268template<typename BasicJsonType, typename T>
3269struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3270{
3271 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3272
3273 static constexpr bool value =
3275 const BasicJsonType&>::value;
3276};
3277
3278// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3279// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3280template<typename BasicJsonType, typename T, typename = void>
3281struct has_to_json : std::false_type {};
3282
3283template<typename BasicJsonType, typename T>
3284struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3285{
3286 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3287
3288 static constexpr bool value =
3289 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3290 T>::value;
3291};
3292
3293template<typename T>
3294using detect_key_compare = typename T::key_compare;
3295
3296template<typename T>
3297struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3298
3299// obtains the actual object key comparator
3300template<typename BasicJsonType>
3302{
3303 using object_t = typename BasicJsonType::object_t;
3304 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3305 using type = typename std::conditional < has_key_compare<object_t>::value,
3306 typename object_t::key_compare, object_comparator_t>::type;
3307};
3308
3309template<typename BasicJsonType>
3311
3313// is_ functions //
3315
3316// https://en.cppreference.com/w/cpp/types/conjunction
3317template<class...> struct conjunction : std::true_type { };
3318template<class B> struct conjunction<B> : B { };
3319template<class B, class... Bn>
3320struct conjunction<B, Bn...>
3321: std::conditional<bool(B::value), conjunction<Bn...>, B>::type {};
3322
3323// https://en.cppreference.com/w/cpp/types/negation
3324template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3325
3326// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3327// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3328// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3329template <typename T>
3330struct is_default_constructible : std::is_default_constructible<T> {};
3331
3332template <typename T1, typename T2>
3333struct is_default_constructible<std::pair<T1, T2>>
3334 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3335
3336template <typename T1, typename T2>
3337struct is_default_constructible<const std::pair<T1, T2>>
3338 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3339
3340template <typename... Ts>
3341struct is_default_constructible<std::tuple<Ts...>>
3342 : conjunction<is_default_constructible<Ts>...> {};
3343
3344template <typename... Ts>
3345struct is_default_constructible<const std::tuple<Ts...>>
3346 : conjunction<is_default_constructible<Ts>...> {};
3347
3348
3349template <typename T, typename... Args>
3350struct is_constructible : std::is_constructible<T, Args...> {};
3351
3352template <typename T1, typename T2>
3353struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3354
3355template <typename T1, typename T2>
3356struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3357
3358template <typename... Ts>
3359struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3360
3361template <typename... Ts>
3362struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3363
3364
3365template<typename T, typename = void>
3366struct is_iterator_traits : std::false_type {};
3367
3368template<typename T>
3370{
3371 private:
3372 using traits = iterator_traits<T>;
3373
3374 public:
3375 static constexpr auto value =
3381};
3382
3383template<typename T>
3385{
3386 private:
3387 using t_ref = typename std::add_lvalue_reference<T>::type;
3388
3389 using iterator = detected_t<result_of_begin, t_ref>;
3390 using sentinel = detected_t<result_of_end, t_ref>;
3391
3392 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3393 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3394 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3395 static constexpr auto is_iterator_begin =
3397
3398 public:
3399 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3400};
3401
3402template<typename R>
3403using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3404
3405template<typename T>
3407
3408// The following implementation of is_complete_type is taken from
3409// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3410// and is written by Xiang Fan who agreed to using it in this library.
3411
3412template<typename T, typename = void>
3413struct is_complete_type : std::false_type {};
3414
3415template<typename T>
3416struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3417
3418template<typename BasicJsonType, typename CompatibleObjectType,
3419 typename = void>
3420struct is_compatible_object_type_impl : std::false_type {};
3421
3422template<typename BasicJsonType, typename CompatibleObjectType>
3424 BasicJsonType, CompatibleObjectType,
3425 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3426 is_detected<key_type_t, CompatibleObjectType>::value >>
3427{
3428 using object_t = typename BasicJsonType::object_t;
3429
3430 // macOS's is_constructible does not play well with nonesuch...
3431 static constexpr bool value =
3432 is_constructible<typename object_t::key_type,
3433 typename CompatibleObjectType::key_type>::value &&
3434 is_constructible<typename object_t::mapped_type,
3435 typename CompatibleObjectType::mapped_type>::value;
3436};
3437
3438template<typename BasicJsonType, typename CompatibleObjectType>
3440 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3441
3442template<typename BasicJsonType, typename ConstructibleObjectType,
3443 typename = void>
3444struct is_constructible_object_type_impl : std::false_type {};
3445
3446template<typename BasicJsonType, typename ConstructibleObjectType>
3448 BasicJsonType, ConstructibleObjectType,
3449 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3450 is_detected<key_type_t, ConstructibleObjectType>::value >>
3451{
3452 using object_t = typename BasicJsonType::object_t;
3453
3454 static constexpr bool value =
3456 (std::is_move_assignable<ConstructibleObjectType>::value ||
3457 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3458 (is_constructible<typename ConstructibleObjectType::key_type,
3459 typename object_t::key_type>::value &&
3460 std::is_same <
3461 typename object_t::mapped_type,
3462 typename ConstructibleObjectType::mapped_type >::value)) ||
3463 (has_from_json<BasicJsonType,
3464 typename ConstructibleObjectType::mapped_type>::value ||
3466 BasicJsonType,
3467 typename ConstructibleObjectType::mapped_type >::value);
3468};
3469
3470template<typename BasicJsonType, typename ConstructibleObjectType>
3472 : is_constructible_object_type_impl<BasicJsonType,
3473 ConstructibleObjectType> {};
3474
3475template<typename BasicJsonType, typename CompatibleStringType>
3477{
3478 static constexpr auto value =
3480};
3481
3482template<typename BasicJsonType, typename ConstructibleStringType>
3484{
3485 // launder type through decltype() to fix compilation failure on ICPC
3486#ifdef __INTEL_COMPILER
3487 using laundered_type = decltype(std::declval<ConstructibleStringType>());
3488#else
3489 using laundered_type = ConstructibleStringType;
3490#endif
3491
3492 static constexpr auto value =
3494 typename BasicJsonType::string_t>::value;
3495};
3496
3497template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3498struct is_compatible_array_type_impl : std::false_type {};
3499
3500template<typename BasicJsonType, typename CompatibleArrayType>
3502 BasicJsonType, CompatibleArrayType,
3503 enable_if_t <
3504 is_detected<iterator_t, CompatibleArrayType>::value&&
3505 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3506// special case for types like std::filesystem::path whose iterator's value_type are themselves
3507// c.f. https://github.com/nlohmann/json/pull/3073
3508 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3509{
3510 static constexpr bool value =
3511 is_constructible<BasicJsonType,
3513};
3514
3515template<typename BasicJsonType, typename CompatibleArrayType>
3517 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3518
3519template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3520struct is_constructible_array_type_impl : std::false_type {};
3521
3522template<typename BasicJsonType, typename ConstructibleArrayType>
3524 BasicJsonType, ConstructibleArrayType,
3525 enable_if_t<std::is_same<ConstructibleArrayType,
3526 typename BasicJsonType::value_type>::value >>
3527 : std::true_type {};
3528
3529template<typename BasicJsonType, typename ConstructibleArrayType>
3531 BasicJsonType, ConstructibleArrayType,
3532 enable_if_t < !std::is_same<ConstructibleArrayType,
3533 typename BasicJsonType::value_type>::value&&
3534 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3535 is_default_constructible<ConstructibleArrayType>::value&&
3536(std::is_move_assignable<ConstructibleArrayType>::value ||
3537 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3538is_detected<iterator_t, ConstructibleArrayType>::value&&
3539is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3540is_detected<range_value_t, ConstructibleArrayType>::value&&
3541// special case for types like std::filesystem::path whose iterator's value_type are themselves
3542// c.f. https://github.com/nlohmann/json/pull/3073
3543!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3545 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3546{
3548
3549 static constexpr bool value =
3550 std::is_same<value_type,
3551 typename BasicJsonType::array_t::value_type>::value ||
3552 has_from_json<BasicJsonType,
3553 value_type>::value ||
3555 BasicJsonType,
3556 value_type >::value;
3557};
3558
3559template<typename BasicJsonType, typename ConstructibleArrayType>
3561 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3562
3563template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3564 typename = void>
3565struct is_compatible_integer_type_impl : std::false_type {};
3566
3567template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3569 RealIntegerType, CompatibleNumberIntegerType,
3570 enable_if_t < std::is_integral<RealIntegerType>::value&&
3571 std::is_integral<CompatibleNumberIntegerType>::value&&
3572 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3573{
3574 // is there an assert somewhere on overflows?
3575 using RealLimits = std::numeric_limits<RealIntegerType>;
3576 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3577
3578 static constexpr auto value =
3579 is_constructible<RealIntegerType,
3580 CompatibleNumberIntegerType>::value &&
3581 CompatibleLimits::is_integer &&
3582 RealLimits::is_signed == CompatibleLimits::is_signed;
3583};
3584
3585template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3587 : is_compatible_integer_type_impl<RealIntegerType,
3588 CompatibleNumberIntegerType> {};
3589
3590template<typename BasicJsonType, typename CompatibleType, typename = void>
3591struct is_compatible_type_impl: std::false_type {};
3592
3593template<typename BasicJsonType, typename CompatibleType>
3595 BasicJsonType, CompatibleType,
3596 enable_if_t<is_complete_type<CompatibleType>::value >>
3597{
3598 static constexpr bool value =
3600};
3601
3602template<typename BasicJsonType, typename CompatibleType>
3604 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3605
3606template<typename T1, typename T2>
3607struct is_constructible_tuple : std::false_type {};
3608
3609template<typename T1, typename... Args>
3610struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3611
3612template<typename BasicJsonType, typename T>
3613struct is_json_iterator_of : std::false_type {};
3614
3615template<typename BasicJsonType>
3616struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3617
3618template<typename BasicJsonType>
3619struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3620{};
3621
3622// checks if a given type T is a template specialization of Primary
3623template<template <typename...> class Primary, typename T>
3624struct is_specialization_of : std::false_type {};
3625
3626template<template <typename...> class Primary, typename... Args>
3627struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3628
3629template<typename T>
3631
3632// checks if A and B are comparable using Compare functor
3633template<typename Compare, typename A, typename B, typename = void>
3634struct is_comparable : std::false_type {};
3635
3636template<typename Compare, typename A, typename B>
3637struct is_comparable<Compare, A, B, void_t<
3638decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3639decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3640>> : std::true_type {};
3641
3642// checks if BasicJsonType::object_t::key_type and KeyType are comparable using Compare functor
3643template<typename BasicJsonType, typename KeyType>
3645 typename BasicJsonType::object_comparator_t,
3647 KeyType >::type;
3648
3649template<typename T>
3650using detect_is_transparent = typename T::is_transparent;
3651
3652// type trait to check if KeyType can be used as object key
3653// true if:
3654// - KeyType is comparable with BasicJsonType::object_t::key_type
3655// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3656// - the comparator is transparent or RequireTransparentComparator is false
3657// - KeyType is not a JSON iterator or json_pointer
3658template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3659 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3660using is_usable_as_key_type = typename std::conditional <
3662 && !(ExcludeObjectKeyType && std::is_same<KeyType,
3663 typename BasicJsonType::object_t::key_type>::value)
3664 && (!RequireTransparentComparator || is_detected <
3666 typename BasicJsonType::object_comparator_t >::value)
3669 std::true_type,
3670 std::false_type >::type;
3671
3672template<typename ObjectType, typename KeyType>
3673using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3674
3675// type trait to check if object_t has an erase() member functions accepting KeyType
3676template<typename BasicJsonType, typename KeyType>
3677using has_erase_with_key_type = typename std::conditional <
3678 is_detected <
3680 typename BasicJsonType::object_t, KeyType >::value,
3681 std::true_type,
3682 std::false_type >::type;
3683
3684// a naive helper to check if a type is an ordered_map (exploits the fact that
3685// ordered_map inherits capacity() from std::vector)
3686template <typename T>
3688{
3689 using one = char;
3690
3691 struct two
3692 {
3693 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3694 };
3695
3696 template <typename C> static one test( decltype(&C::capacity) ) ;
3697 template <typename C> static two test(...);
3698
3699 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3700};
3701
3702// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3703template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3705{
3706 return static_cast<T>(value);
3707}
3708
3709template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3710T conditional_static_cast(U value)
3711{
3712 return value;
3713}
3714
3715} // namespace detail
3716} // namespace nlohmann
3717
3718// #include <nlohmann/detail/string_concat.hpp>
3719
3720
3721#include <cstring> // strlen
3722#include <string> // string
3723#include <utility> // forward
3724
3725// #include <nlohmann/detail/meta/cpp_future.hpp>
3726
3727// #include <nlohmann/detail/meta/detected.hpp>
3728
3729
3730namespace nlohmann
3731{
3732namespace detail
3733{
3734
3735inline std::size_t concat_length()
3736{
3737 return 0;
3738}
3739
3740template<typename... Args>
3741inline std::size_t concat_length(const char* cstr, Args&& ... rest);
3742
3743template<typename StringType, typename... Args>
3744inline std::size_t concat_length(const StringType& str, Args&& ... rest);
3745
3746template<typename... Args>
3747inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
3748{
3749 return 1 + concat_length(std::forward<Args>(rest)...);
3750}
3751
3752template<typename... Args>
3753inline std::size_t concat_length(const char* cstr, Args&& ... rest)
3754{
3755 // cppcheck-suppress ignoredReturnValue
3756 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
3757}
3758
3759template<typename StringType, typename... Args>
3760inline std::size_t concat_length(const StringType& str, Args&& ... rest)
3761{
3762 return str.size() + concat_length(std::forward<Args>(rest)...);
3763}
3764
3765template<typename OutStringType>
3766inline void concat_into(OutStringType& /*out*/)
3767{}
3768
3769template<typename StringType, typename Arg>
3770using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
3771
3772template<typename StringType, typename Arg>
3774
3775template<typename StringType, typename Arg>
3776using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
3777
3778template<typename StringType, typename Arg>
3780
3781template<typename StringType, typename Arg>
3782using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
3783
3784template<typename StringType, typename Arg>
3786
3787template<typename StringType, typename Arg>
3788using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
3789
3790template<typename StringType, typename Arg>
3792
3793template < typename OutStringType, typename Arg, typename... Args,
3796inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
3797
3798template < typename OutStringType, typename Arg, typename... Args,
3802inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3803
3804template < typename OutStringType, typename Arg, typename... Args,
3809inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3810
3811template<typename OutStringType, typename Arg, typename... Args,
3813inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
3814{
3815 out.append(std::forward<Arg>(arg));
3816 concat_into(out, std::forward<Args>(rest)...);
3817}
3818
3819template < typename OutStringType, typename Arg, typename... Args,
3820 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3821 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
3822inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
3823{
3824 out += std::forward<Arg>(arg);
3825 concat_into(out, std::forward<Args>(rest)...);
3826}
3827
3828template < typename OutStringType, typename Arg, typename... Args,
3829 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3830 && !detect_string_can_append_op<OutStringType, Arg>::value
3831 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
3832inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3833{
3834 out.append(arg.begin(), arg.end());
3835 concat_into(out, std::forward<Args>(rest)...);
3836}
3837
3838template < typename OutStringType, typename Arg, typename... Args,
3839 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3840 && !detect_string_can_append_op<OutStringType, Arg>::value
3841 && !detect_string_can_append_iter<OutStringType, Arg>::value
3842 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
3843inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3844{
3845 out.append(arg.data(), arg.size());
3846 concat_into(out, std::forward<Args>(rest)...);
3847}
3848
3849template<typename OutStringType = std::string, typename... Args>
3850inline OutStringType concat(Args && ... args)
3851{
3852 OutStringType str;
3853 str.reserve(concat_length(std::forward<Args>(args)...));
3854 concat_into(str, std::forward<Args>(args)...);
3855 return str;
3856}
3857
3858} // namespace detail
3859} // namespace nlohmann
3860
3861
3862
3863namespace nlohmann
3864{
3865namespace detail
3866{
3868// exceptions //
3870
3873class exception : public std::exception
3874{
3875 public:
3877 const char* what() const noexcept override
3878 {
3879 return m.what();
3880 }
3881
3883 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
3884
3885 protected:
3887 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
3888
3889 static std::string name(const std::string& ename, int id_)
3890 {
3891 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
3892 }
3893
3894 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
3895 {
3896 return "";
3897 }
3898
3899 template<typename BasicJsonType>
3900 static std::string diagnostics(const BasicJsonType* leaf_element)
3901 {
3902#if JSON_DIAGNOSTICS
3903 std::vector<std::string> tokens;
3904 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
3905 {
3906 switch (current->m_parent->type())
3907 {
3908 case value_t::array:
3909 {
3910 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
3911 {
3912 if (&current->m_parent->m_value.array->operator[](i) == current)
3913 {
3914 tokens.emplace_back(std::to_string(i));
3915 break;
3916 }
3917 }
3918 break;
3919 }
3920
3921 case value_t::object:
3922 {
3923 for (const auto& element : *current->m_parent->m_value.object)
3924 {
3925 if (&element.second == current)
3926 {
3927 tokens.emplace_back(element.first.c_str());
3928 break;
3929 }
3930 }
3931 break;
3932 }
3933
3934 case value_t::null: // LCOV_EXCL_LINE
3935 case value_t::string: // LCOV_EXCL_LINE
3936 case value_t::boolean: // LCOV_EXCL_LINE
3937 case value_t::number_integer: // LCOV_EXCL_LINE
3938 case value_t::number_unsigned: // LCOV_EXCL_LINE
3939 case value_t::number_float: // LCOV_EXCL_LINE
3940 case value_t::binary: // LCOV_EXCL_LINE
3941 case value_t::discarded: // LCOV_EXCL_LINE
3942 default: // LCOV_EXCL_LINE
3943 break; // LCOV_EXCL_LINE
3944 }
3945 }
3946
3947 if (tokens.empty())
3948 {
3949 return "";
3950 }
3951
3952 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
3953 [](const std::string & a, const std::string & b)
3954 {
3955 return concat(a, '/', detail::escape(b));
3956 });
3957 return concat('(', str, ") ");
3958#else
3959 static_cast<void>(leaf_element);
3960 return "";
3961#endif
3962 }
3963
3964 private:
3966 std::runtime_error m;
3967};
3968
3972{
3973 public:
3983 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
3984 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
3985 {
3986 std::string w = concat(exception::name("parse_error", id_), "parse error",
3987 position_string(pos), ": ", exception::diagnostics(context), what_arg);
3988 return {id_, pos.chars_read_total, w.c_str()};
3989 }
3990
3991 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
3992 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
3993 {
3994 std::string w = concat(exception::name("parse_error", id_), "parse error",
3995 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
3996 ": ", exception::diagnostics(context), what_arg);
3997 return {id_, byte_, w.c_str()};
3998 }
3999
4009 const std::size_t byte;
4010
4011 private:
4012 parse_error(int id_, std::size_t byte_, const char* what_arg)
4013 : exception(id_, what_arg), byte(byte_) {}
4014
4015 static std::string position_string(const position_t& pos)
4016 {
4017 return concat(" at line ", std::to_string(pos.lines_read + 1),
4018 ", column ", std::to_string(pos.chars_read_current_line));
4019 }
4020};
4021
4025{
4026 public:
4027 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4028 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4029 {
4030 std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4031 return {id_, w.c_str()};
4032 }
4033
4034 private:
4036 invalid_iterator(int id_, const char* what_arg)
4037 : exception(id_, what_arg) {}
4038};
4039
4042class type_error : public exception
4043{
4044 public:
4045 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4046 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4047 {
4048 std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4049 return {id_, w.c_str()};
4050 }
4051
4052 private:
4054 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4055};
4056
4060{
4061 public:
4062 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4063 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4064 {
4065 std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4066 return {id_, w.c_str()};
4067 }
4068
4069 private:
4071 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4072};
4073
4077{
4078 public:
4079 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4080 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4081 {
4082 std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4083 return {id_, w.c_str()};
4084 }
4085
4086 private:
4088 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4089};
4090
4091} // namespace detail
4092} // namespace nlohmann
4093
4094// #include <nlohmann/detail/macro_scope.hpp>
4095
4096// #include <nlohmann/detail/meta/cpp_future.hpp>
4097
4098// #include <nlohmann/detail/meta/identity_tag.hpp>
4099
4100
4101namespace nlohmann
4102{
4103namespace detail
4104{
4105// dispatching helper struct
4106template <class T> struct identity_tag {};
4107} // namespace detail
4108} // namespace nlohmann
4109
4110// #include <nlohmann/detail/meta/type_traits.hpp>
4111
4112// #include <nlohmann/detail/string_concat.hpp>
4113
4114// #include <nlohmann/detail/value_t.hpp>
4115
4116
4117#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4118#include <experimental/filesystem>
4119namespace nlohmann::detail
4120{
4121namespace std_fs = std::experimental::filesystem;
4122} // namespace nlohmann::detail
4123#elif JSON_HAS_FILESYSTEM
4124#include <filesystem>
4125namespace nlohmann::detail
4126{
4127namespace std_fs = std::filesystem;
4128} // namespace nlohmann::detail
4129#endif
4130
4131namespace nlohmann
4132{
4133namespace detail
4134{
4135template<typename BasicJsonType>
4136void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4137{
4138 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4139 {
4140 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4141 }
4142 n = nullptr;
4143}
4144
4145// overloads for basic_json template parameters
4146template < typename BasicJsonType, typename ArithmeticType,
4147 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4148 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4149 int > = 0 >
4150void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4151{
4152 switch (static_cast<value_t>(j))
4153 {
4155 {
4156 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4157 break;
4158 }
4160 {
4161 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4162 break;
4163 }
4165 {
4166 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4167 break;
4168 }
4169
4170 case value_t::null:
4171 case value_t::object:
4172 case value_t::array:
4173 case value_t::string:
4174 case value_t::boolean:
4175 case value_t::binary:
4176 case value_t::discarded:
4177 default:
4178 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4179 }
4180}
4181
4182template<typename BasicJsonType>
4183void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4184{
4185 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4186 {
4187 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4188 }
4189 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4190}
4191
4192template<typename BasicJsonType>
4193void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4194{
4195 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4196 {
4197 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4198 }
4199 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4200}
4201
4202template <
4203 typename BasicJsonType, typename StringType,
4204 enable_if_t <
4205 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4206 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4207 && !is_json_ref<StringType>::value, int > = 0 >
4208void from_json(const BasicJsonType& j, StringType& s)
4209{
4210 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4211 {
4212 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4213 }
4214
4215 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4216}
4217
4218template<typename BasicJsonType>
4219void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4220{
4221 get_arithmetic_value(j, val);
4222}
4223
4224template<typename BasicJsonType>
4225void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4226{
4227 get_arithmetic_value(j, val);
4228}
4229
4230template<typename BasicJsonType>
4231void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4232{
4233 get_arithmetic_value(j, val);
4234}
4235
4236template<typename BasicJsonType, typename EnumType,
4237 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4238void from_json(const BasicJsonType& j, EnumType& e)
4239{
4240 typename std::underlying_type<EnumType>::type val;
4241 get_arithmetic_value(j, val);
4242 e = static_cast<EnumType>(val);
4243}
4244
4245// forward_list doesn't have an insert method
4246template<typename BasicJsonType, typename T, typename Allocator,
4247 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4248void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4249{
4250 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4251 {
4252 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4253 }
4254 l.clear();
4255 std::transform(j.rbegin(), j.rend(),
4256 std::front_inserter(l), [](const BasicJsonType & i)
4257 {
4258 return i.template get<T>();
4259 });
4260}
4261
4262// valarray doesn't have an insert method
4263template<typename BasicJsonType, typename T,
4264 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4265void from_json(const BasicJsonType& j, std::valarray<T>& l)
4266{
4267 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4268 {
4269 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4270 }
4271 l.resize(j.size());
4272 std::transform(j.begin(), j.end(), std::begin(l),
4273 [](const BasicJsonType & elem)
4274 {
4275 return elem.template get<T>();
4276 });
4277}
4278
4279template<typename BasicJsonType, typename T, std::size_t N>
4280auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4281-> decltype(j.template get<T>(), void())
4282{
4283 for (std::size_t i = 0; i < N; ++i)
4284 {
4285 arr[i] = j.at(i).template get<T>();
4286 }
4287}
4288
4289template<typename BasicJsonType>
4290void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4291{
4292 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4293}
4294
4295template<typename BasicJsonType, typename T, std::size_t N>
4296auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4297 priority_tag<2> /*unused*/)
4298-> decltype(j.template get<T>(), void())
4299{
4300 for (std::size_t i = 0; i < N; ++i)
4301 {
4302 arr[i] = j.at(i).template get<T>();
4303 }
4304}
4305
4306template<typename BasicJsonType, typename ConstructibleArrayType,
4308 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4309 int> = 0>
4310auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4311-> decltype(
4312 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4313 j.template get<typename ConstructibleArrayType::value_type>(),
4314 void())
4315{
4316 using std::end;
4317
4318 ConstructibleArrayType ret;
4319 ret.reserve(j.size());
4320 std::transform(j.begin(), j.end(),
4321 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4322 {
4323 // get<BasicJsonType>() returns *this, this won't call a from_json
4324 // method when value_type is BasicJsonType
4325 return i.template get<typename ConstructibleArrayType::value_type>();
4326 });
4327 arr = std::move(ret);
4328}
4329
4330template<typename BasicJsonType, typename ConstructibleArrayType,
4332 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4333 int> = 0>
4334void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4335 priority_tag<0> /*unused*/)
4336{
4337 using std::end;
4338
4339 ConstructibleArrayType ret;
4340 std::transform(
4341 j.begin(), j.end(), std::inserter(ret, end(ret)),
4342 [](const BasicJsonType & i)
4343 {
4344 // get<BasicJsonType>() returns *this, this won't call a from_json
4345 // method when value_type is BasicJsonType
4346 return i.template get<typename ConstructibleArrayType::value_type>();
4347 });
4348 arr = std::move(ret);
4349}
4350
4351template < typename BasicJsonType, typename ConstructibleArrayType,
4352 enable_if_t <
4353 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4354 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4356 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4357 !is_basic_json<ConstructibleArrayType>::value,
4358 int > = 0 >
4359auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4360-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4361j.template get<typename ConstructibleArrayType::value_type>(),
4362void())
4363{
4364 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4365 {
4366 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4367 }
4368
4369 from_json_array_impl(j, arr, priority_tag<3> {});
4370}
4371
4372template < typename BasicJsonType, typename T, std::size_t... Idx >
4373std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4374 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4375{
4376 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4377}
4378
4379template < typename BasicJsonType, typename T, std::size_t N >
4380auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4381-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4382{
4383 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4384 {
4385 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4386 }
4387
4388 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4389}
4390
4391template<typename BasicJsonType>
4392void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4393{
4394 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4395 {
4396 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4397 }
4398
4399 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4400}
4401
4402template<typename BasicJsonType, typename ConstructibleObjectType,
4403 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4404void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4405{
4406 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4407 {
4408 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4409 }
4410
4411 ConstructibleObjectType ret;
4412 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4413 using value_type = typename ConstructibleObjectType::value_type;
4414 std::transform(
4415 inner_object->begin(), inner_object->end(),
4416 std::inserter(ret, ret.begin()),
4417 [](typename BasicJsonType::object_t::value_type const & p)
4418 {
4419 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4420 });
4421 obj = std::move(ret);
4422}
4423
4424// overload for arithmetic types, not chosen for basic_json template arguments
4425// (BooleanType, etc..); note: Is it really necessary to provide explicit
4426// overloads for boolean_t etc. in case of a custom BooleanType which is not
4427// an arithmetic type?
4428template < typename BasicJsonType, typename ArithmeticType,
4429 enable_if_t <
4430 std::is_arithmetic<ArithmeticType>::value&&
4431 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4432 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4433 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4434 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4435 int > = 0 >
4436void from_json(const BasicJsonType& j, ArithmeticType& val)
4437{
4438 switch (static_cast<value_t>(j))
4439 {
4441 {
4442 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4443 break;
4444 }
4446 {
4447 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4448 break;
4449 }
4451 {
4452 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4453 break;
4454 }
4455 case value_t::boolean:
4456 {
4457 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4458 break;
4459 }
4460
4461 case value_t::null:
4462 case value_t::object:
4463 case value_t::array:
4464 case value_t::string:
4465 case value_t::binary:
4466 case value_t::discarded:
4467 default:
4468 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4469 }
4470}
4471
4472template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4473std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4474{
4475 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4476}
4477
4478template < typename BasicJsonType, class A1, class A2 >
4479std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4480{
4481 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4482 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4483}
4484
4485template<typename BasicJsonType, typename A1, typename A2>
4486void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4487{
4488 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4489}
4490
4491template<typename BasicJsonType, typename... Args>
4492std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4493{
4494 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4495}
4496
4497template<typename BasicJsonType, typename... Args>
4498void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4499{
4500 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4501}
4502
4503template<typename BasicJsonType, typename TupleRelated>
4504auto from_json(BasicJsonType&& j, TupleRelated&& t)
4505-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4506{
4507 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4508 {
4509 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4510 }
4511
4512 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4513}
4514
4515template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4516 typename = enable_if_t < !std::is_constructible <
4517 typename BasicJsonType::string_t, Key >::value >>
4518void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4519{
4520 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4521 {
4522 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4523 }
4524 m.clear();
4525 for (const auto& p : j)
4526 {
4527 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4528 {
4529 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4530 }
4531 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4532 }
4533}
4534
4535template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4536 typename = enable_if_t < !std::is_constructible <
4537 typename BasicJsonType::string_t, Key >::value >>
4538void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4539{
4540 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4541 {
4542 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4543 }
4544 m.clear();
4545 for (const auto& p : j)
4546 {
4547 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4548 {
4549 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4550 }
4551 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4552 }
4553}
4554
4555#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4556template<typename BasicJsonType>
4557void from_json(const BasicJsonType& j, std_fs::path& p)
4558{
4559 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4560 {
4561 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4562 }
4563 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4564}
4565#endif
4566
4568{
4569 template<typename BasicJsonType, typename T>
4570 auto operator()(const BasicJsonType& j, T&& val) const
4571 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4572 -> decltype(from_json(j, std::forward<T>(val)))
4573 {
4574 return from_json(j, std::forward<T>(val));
4575 }
4576};
4577} // namespace detail
4578
4582namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4583{
4584constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4585} // namespace
4586} // namespace nlohmann
4587
4588// #include <nlohmann/detail/conversions/to_json.hpp>
4589
4590
4591#include <algorithm> // copy
4592#include <iterator> // begin, end
4593#include <string> // string
4594#include <tuple> // tuple, get
4595#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4596#include <utility> // move, forward, declval, pair
4597#include <valarray> // valarray
4598#include <vector> // vector
4599
4600// #include <nlohmann/detail/macro_scope.hpp>
4601
4602// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4603
4604
4605#include <cstddef> // size_t
4606#include <iterator> // input_iterator_tag
4607#include <string> // string, to_string
4608#include <tuple> // tuple_size, get, tuple_element
4609#include <utility> // move
4610
4611// #include <nlohmann/detail/meta/type_traits.hpp>
4612
4613// #include <nlohmann/detail/value_t.hpp>
4614
4615
4616namespace nlohmann
4617{
4618namespace detail
4619{
4620template<typename string_type>
4621void int_to_string( string_type& target, std::size_t value )
4622{
4623 // For ADL
4624 using std::to_string;
4625 target = to_string(value);
4626}
4627template<typename IteratorType> class iteration_proxy_value
4628{
4629 public:
4630 using difference_type = std::ptrdiff_t;
4634 using iterator_category = std::input_iterator_tag;
4635 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4636
4637 private:
4639 IteratorType anchor;
4641 std::size_t array_index = 0;
4643 mutable std::size_t array_index_last = 0;
4645 mutable string_type array_index_str = "0";
4647 const string_type empty_str{};
4648
4649 public:
4650 explicit iteration_proxy_value(IteratorType it) noexcept
4651 : anchor(std::move(it))
4652 {}
4653
4656 {
4657 return *this;
4658 }
4659
4662 {
4663 ++anchor;
4664 ++array_index;
4665
4666 return *this;
4667 }
4668
4671 {
4672 return anchor == o.anchor;
4673 }
4674
4677 {
4678 return anchor != o.anchor;
4679 }
4680
4682 const string_type& key() const
4683 {
4684 JSON_ASSERT(anchor.m_object != nullptr);
4685
4686 switch (anchor.m_object->type())
4687 {
4688 // use integer array index as key
4689 case value_t::array:
4690 {
4691 if (array_index != array_index_last)
4692 {
4693 int_to_string( array_index_str, array_index );
4694 array_index_last = array_index;
4695 }
4696 return array_index_str;
4697 }
4698
4699 // use key from the object
4700 case value_t::object:
4701 return anchor.key();
4702
4703 // use an empty key for all primitive types
4704 case value_t::null:
4705 case value_t::string:
4706 case value_t::boolean:
4710 case value_t::binary:
4711 case value_t::discarded:
4712 default:
4713 return empty_str;
4714 }
4715 }
4716
4718 typename IteratorType::reference value() const
4719 {
4720 return anchor.value();
4721 }
4722};
4723
4725template<typename IteratorType> class iteration_proxy
4726{
4727 private:
4729 typename IteratorType::reference container;
4730
4731 public:
4733 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4734 : container(cont) {}
4735
4738 {
4739 return iteration_proxy_value<IteratorType>(container.begin());
4740 }
4741
4744 {
4745 return iteration_proxy_value<IteratorType>(container.end());
4746 }
4747};
4748// Structured Bindings Support
4749// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4750// And see https://github.com/nlohmann/json/pull/1391
4751template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4753{
4754 return i.key();
4755}
4756// Structured Bindings Support
4757// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4758// And see https://github.com/nlohmann/json/pull/1391
4759template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4760auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4761{
4762 return i.value();
4763}
4764} // namespace detail
4765} // namespace nlohmann
4766
4767// The Addition to the STD Namespace is required to add
4768// Structured Bindings Support to the iteration_proxy_value class
4769// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4770// And see https://github.com/nlohmann/json/pull/1391
4771namespace std
4772{
4773#if defined(__clang__)
4774 // Fix: https://github.com/nlohmann/json/issues/1401
4775 #pragma clang diagnostic push
4776 #pragma clang diagnostic ignored "-Wmismatched-tags"
4777#endif
4778template<typename IteratorType>
4779class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4780 : public std::integral_constant<std::size_t, 2> {};
4781
4782template<std::size_t N, typename IteratorType>
4783class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4784{
4785 public:
4786 using type = decltype(
4787 get<N>(std::declval <
4789};
4790#if defined(__clang__)
4791 #pragma clang diagnostic pop
4792#endif
4793} // namespace std
4794
4795// #include <nlohmann/detail/meta/cpp_future.hpp>
4796
4797// #include <nlohmann/detail/meta/type_traits.hpp>
4798
4799// #include <nlohmann/detail/value_t.hpp>
4800
4801
4802#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4803#include <experimental/filesystem>
4804namespace nlohmann::detail
4805{
4806namespace std_fs = std::experimental::filesystem;
4807} // namespace nlohmann::detail
4808#elif JSON_HAS_FILESYSTEM
4809#include <filesystem>
4810namespace nlohmann::detail
4811{
4812namespace std_fs = std::filesystem;
4813} // namespace nlohmann::detail
4814#endif
4815
4816namespace nlohmann
4817{
4818namespace detail
4819{
4821// constructors //
4823
4824/*
4825 * Note all external_constructor<>::construct functions need to call
4826 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4827 * allocated value (e.g., a string). See bug issue
4828 * https://github.com/nlohmann/json/issues/2865 for more information.
4829 */
4830
4831template<value_t> struct external_constructor;
4832
4833template<>
4835{
4836 template<typename BasicJsonType>
4837 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4838 {
4839 j.m_value.destroy(j.m_type);
4840 j.m_type = value_t::boolean;
4841 j.m_value = b;
4842 j.assert_invariant();
4843 }
4844};
4845
4846template<>
4848{
4849 template<typename BasicJsonType>
4850 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4851 {
4852 j.m_value.destroy(j.m_type);
4853 j.m_type = value_t::string;
4854 j.m_value = s;
4855 j.assert_invariant();
4856 }
4857
4858 template<typename BasicJsonType>
4859 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4860 {
4861 j.m_value.destroy(j.m_type);
4862 j.m_type = value_t::string;
4863 j.m_value = std::move(s);
4864 j.assert_invariant();
4865 }
4866
4867 template < typename BasicJsonType, typename CompatibleStringType,
4869 int > = 0 >
4870 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4871 {
4872 j.m_value.destroy(j.m_type);
4873 j.m_type = value_t::string;
4874 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4875 j.assert_invariant();
4876 }
4877};
4878
4879template<>
4881{
4882 template<typename BasicJsonType>
4883 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4884 {
4885 j.m_value.destroy(j.m_type);
4886 j.m_type = value_t::binary;
4887 j.m_value = typename BasicJsonType::binary_t(b);
4888 j.assert_invariant();
4889 }
4890
4891 template<typename BasicJsonType>
4892 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4893 {
4894 j.m_value.destroy(j.m_type);
4895 j.m_type = value_t::binary;
4896 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4897 j.assert_invariant();
4898 }
4899};
4900
4901template<>
4903{
4904 template<typename BasicJsonType>
4905 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4906 {
4907 j.m_value.destroy(j.m_type);
4908 j.m_type = value_t::number_float;
4909 j.m_value = val;
4910 j.assert_invariant();
4911 }
4912};
4913
4914template<>
4916{
4917 template<typename BasicJsonType>
4918 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4919 {
4920 j.m_value.destroy(j.m_type);
4921 j.m_type = value_t::number_unsigned;
4922 j.m_value = val;
4923 j.assert_invariant();
4924 }
4925};
4926
4927template<>
4929{
4930 template<typename BasicJsonType>
4931 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4932 {
4933 j.m_value.destroy(j.m_type);
4934 j.m_type = value_t::number_integer;
4935 j.m_value = val;
4936 j.assert_invariant();
4937 }
4938};
4939
4940template<>
4942{
4943 template<typename BasicJsonType>
4944 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4945 {
4946 j.m_value.destroy(j.m_type);
4947 j.m_type = value_t::array;
4948 j.m_value = arr;
4949 j.set_parents();
4950 j.assert_invariant();
4951 }
4952
4953 template<typename BasicJsonType>
4954 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4955 {
4956 j.m_value.destroy(j.m_type);
4957 j.m_type = value_t::array;
4958 j.m_value = std::move(arr);
4959 j.set_parents();
4960 j.assert_invariant();
4961 }
4962
4963 template < typename BasicJsonType, typename CompatibleArrayType,
4965 int > = 0 >
4966 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4967 {
4968 using std::begin;
4969 using std::end;
4970
4971 j.m_value.destroy(j.m_type);
4972 j.m_type = value_t::array;
4973 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4974 j.set_parents();
4975 j.assert_invariant();
4976 }
4977
4978 template<typename BasicJsonType>
4979 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4980 {
4981 j.m_value.destroy(j.m_type);
4982 j.m_type = value_t::array;
4983 j.m_value = value_t::array;
4984 j.m_value.array->reserve(arr.size());
4985 for (const bool x : arr)
4986 {
4987 j.m_value.array->push_back(x);
4988 j.set_parent(j.m_value.array->back());
4989 }
4990 j.assert_invariant();
4991 }
4992
4993 template<typename BasicJsonType, typename T,
4995 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4996 {
4997 j.m_value.destroy(j.m_type);
4998 j.m_type = value_t::array;
4999 j.m_value = value_t::array;
5000 j.m_value.array->resize(arr.size());
5001 if (arr.size() > 0)
5002 {
5003 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
5004 }
5005 j.set_parents();
5006 j.assert_invariant();
5007 }
5008};
5009
5010template<>
5012{
5013 template<typename BasicJsonType>
5014 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5015 {
5016 j.m_value.destroy(j.m_type);
5017 j.m_type = value_t::object;
5018 j.m_value = obj;
5019 j.set_parents();
5020 j.assert_invariant();
5021 }
5022
5023 template<typename BasicJsonType>
5024 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5025 {
5026 j.m_value.destroy(j.m_type);
5027 j.m_type = value_t::object;
5028 j.m_value = std::move(obj);
5029 j.set_parents();
5030 j.assert_invariant();
5031 }
5032
5033 template < typename BasicJsonType, typename CompatibleObjectType,
5035 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5036 {
5037 using std::begin;
5038 using std::end;
5039
5040 j.m_value.destroy(j.m_type);
5041 j.m_type = value_t::object;
5042 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5043 j.set_parents();
5044 j.assert_invariant();
5045 }
5046};
5047
5049// to_json //
5051
5052template<typename BasicJsonType, typename T,
5053 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5054void to_json(BasicJsonType& j, T b) noexcept
5055{
5057}
5058
5059template<typename BasicJsonType, typename CompatibleString,
5060 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5061void to_json(BasicJsonType& j, const CompatibleString& s)
5062{
5064}
5065
5066template<typename BasicJsonType>
5067void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5068{
5070}
5071
5072template<typename BasicJsonType, typename FloatType,
5073 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5074void to_json(BasicJsonType& j, FloatType val) noexcept
5075{
5076 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5077}
5078
5079template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5080 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5081void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5082{
5083 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5084}
5085
5086template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5087 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5088void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5089{
5090 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5091}
5092
5093template<typename BasicJsonType, typename EnumType,
5094 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5095void to_json(BasicJsonType& j, EnumType e) noexcept
5096{
5097 using underlying_type = typename std::underlying_type<EnumType>::type;
5098 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5099}
5100
5101template<typename BasicJsonType>
5102void to_json(BasicJsonType& j, const std::vector<bool>& e)
5103{
5105}
5106
5107template < typename BasicJsonType, typename CompatibleArrayType,
5108 enable_if_t < is_compatible_array_type<BasicJsonType,
5109 CompatibleArrayType>::value&&
5110 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
5112 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5113 !is_basic_json<CompatibleArrayType>::value,
5114 int > = 0 >
5115void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5116{
5118}
5119
5120template<typename BasicJsonType>
5121void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5122{
5124}
5125
5126template<typename BasicJsonType, typename T,
5127 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5128void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5129{
5131}
5132
5133template<typename BasicJsonType>
5134void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5135{
5137}
5138
5139template < typename BasicJsonType, typename CompatibleObjectType,
5140 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5141void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5142{
5144}
5145
5146template<typename BasicJsonType>
5147void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5148{
5150}
5151
5152template <
5153 typename BasicJsonType, typename T, std::size_t N,
5154 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5155 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5156 int > = 0 >
5157void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5158{
5160}
5161
5162template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5163void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5164{
5165 j = { p.first, p.second };
5166}
5167
5168// for https://github.com/nlohmann/json/pull/1134
5169template<typename BasicJsonType, typename T,
5170 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5171void to_json(BasicJsonType& j, const T& b)
5172{
5173 j = { {b.key(), b.value()} };
5174}
5175
5176template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5177void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5178{
5179 j = { std::get<Idx>(t)... };
5180}
5181
5182template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5183void to_json(BasicJsonType& j, const T& t)
5184{
5185 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5186}
5187
5188#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5189template<typename BasicJsonType>
5190void to_json(BasicJsonType& j, const std_fs::path& p)
5191{
5192 j = p.string();
5193}
5194#endif
5195
5197{
5198 template<typename BasicJsonType, typename T>
5199 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5200 -> decltype(to_json(j, std::forward<T>(val)), void())
5201 {
5202 return to_json(j, std::forward<T>(val));
5203 }
5204};
5205} // namespace detail
5206
5210namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5211{
5212constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5213} // namespace
5214} // namespace nlohmann
5215
5216// #include <nlohmann/detail/meta/identity_tag.hpp>
5217
5218// #include <nlohmann/detail/meta/type_traits.hpp>
5219
5220
5221namespace nlohmann
5222{
5223
5225template<typename ValueType, typename>
5227{
5230 template<typename BasicJsonType, typename TargetType = ValueType>
5231 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5232 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5233 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5234 {
5235 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5236 }
5237
5240 template<typename BasicJsonType, typename TargetType = ValueType>
5241 static auto from_json(BasicJsonType && j) noexcept(
5242 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5243 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5244 {
5245 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5246 }
5247
5250 template<typename BasicJsonType, typename TargetType = ValueType>
5251 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5252 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5253 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5254 {
5255 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5256 }
5257};
5258} // namespace nlohmann
5259
5260// #include <nlohmann/byte_container_with_subtype.hpp>
5261
5262
5263#include <cstdint> // uint8_t, uint64_t
5264#include <tuple> // tie
5265#include <utility> // move
5266
5267namespace nlohmann
5268{
5269
5272template<typename BinaryType>
5273class byte_container_with_subtype : public BinaryType
5274{
5275 public:
5276 using container_type = BinaryType;
5277 using subtype_type = std::uint64_t;
5278
5281 : container_type()
5282 {}
5283
5286 : container_type(b)
5287 {}
5288
5290 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5291 : container_type(std::move(b))
5292 {}
5293
5296 : container_type(b)
5297 , m_subtype(subtype_)
5298 , m_has_subtype(true)
5299 {}
5300
5302 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5303 : container_type(std::move(b))
5304 , m_subtype(subtype_)
5305 , m_has_subtype(true)
5306 {}
5307
5309 {
5310 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5311 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5312 }
5313
5315 {
5316 return !(rhs == *this);
5317 }
5318
5321 void set_subtype(subtype_type subtype_) noexcept
5322 {
5323 m_subtype = subtype_;
5324 m_has_subtype = true;
5325 }
5326
5329 constexpr subtype_type subtype() const noexcept
5330 {
5331 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5332 }
5333
5336 constexpr bool has_subtype() const noexcept
5337 {
5338 return m_has_subtype;
5339 }
5340
5343 void clear_subtype() noexcept
5344 {
5345 m_subtype = 0;
5346 m_has_subtype = false;
5347 }
5348
5349 private:
5350 subtype_type m_subtype = 0;
5351 bool m_has_subtype = false;
5352};
5353
5354} // namespace nlohmann
5355
5356// #include <nlohmann/detail/conversions/from_json.hpp>
5357
5358// #include <nlohmann/detail/conversions/to_json.hpp>
5359
5360// #include <nlohmann/detail/exceptions.hpp>
5361
5362// #include <nlohmann/detail/hash.hpp>
5363
5364
5365#include <cstdint> // uint8_t
5366#include <cstddef> // size_t
5367#include <functional> // hash
5368
5369// #include <nlohmann/detail/macro_scope.hpp>
5370
5371// #include <nlohmann/detail/value_t.hpp>
5372
5373
5374namespace nlohmann
5375{
5376namespace detail
5377{
5378
5379// boost::hash_combine
5380inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5381{
5382 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5383 return seed;
5384}
5385
5397template<typename BasicJsonType>
5398std::size_t hash(const BasicJsonType& j)
5399{
5400 using string_t = typename BasicJsonType::string_t;
5401 using number_integer_t = typename BasicJsonType::number_integer_t;
5402 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5403 using number_float_t = typename BasicJsonType::number_float_t;
5404
5405 const auto type = static_cast<std::size_t>(j.type());
5406 switch (j.type())
5407 {
5408 case BasicJsonType::value_t::null:
5409 case BasicJsonType::value_t::discarded:
5410 {
5411 return combine(type, 0);
5412 }
5413
5414 case BasicJsonType::value_t::object:
5415 {
5416 auto seed = combine(type, j.size());
5417 for (const auto& element : j.items())
5418 {
5419 const auto h = std::hash<string_t> {}(element.key());
5420 seed = combine(seed, h);
5421 seed = combine(seed, hash(element.value()));
5422 }
5423 return seed;
5424 }
5425
5426 case BasicJsonType::value_t::array:
5427 {
5428 auto seed = combine(type, j.size());
5429 for (const auto& element : j)
5430 {
5431 seed = combine(seed, hash(element));
5432 }
5433 return seed;
5434 }
5435
5436 case BasicJsonType::value_t::string:
5437 {
5438 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5439 return combine(type, h);
5440 }
5441
5442 case BasicJsonType::value_t::boolean:
5443 {
5444 const auto h = std::hash<bool> {}(j.template get<bool>());
5445 return combine(type, h);
5446 }
5447
5448 case BasicJsonType::value_t::number_integer:
5449 {
5450 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5451 return combine(type, h);
5452 }
5453
5454 case BasicJsonType::value_t::number_unsigned:
5455 {
5456 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5457 return combine(type, h);
5458 }
5459
5460 case BasicJsonType::value_t::number_float:
5461 {
5462 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5463 return combine(type, h);
5464 }
5465
5466 case BasicJsonType::value_t::binary:
5467 {
5468 auto seed = combine(type, j.get_binary().size());
5469 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5470 seed = combine(seed, h);
5471 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5472 for (const auto byte : j.get_binary())
5473 {
5474 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5475 }
5476 return seed;
5477 }
5478
5479 default: // LCOV_EXCL_LINE
5480 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5481 return 0; // LCOV_EXCL_LINE
5482 }
5483}
5484
5485} // namespace detail
5486} // namespace nlohmann
5487
5488// #include <nlohmann/detail/input/binary_reader.hpp>
5489
5490
5491#include <algorithm> // generate_n
5492#include <array> // array
5493#include <cmath> // ldexp
5494#include <cstddef> // size_t
5495#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5496#include <cstdio> // snprintf
5497#include <cstring> // memcpy
5498#include <iterator> // back_inserter
5499#include <limits> // numeric_limits
5500#include <string> // char_traits, string
5501#include <utility> // make_pair, move
5502#include <vector> // vector
5503#include <map> // map
5504
5505// #include <nlohmann/detail/exceptions.hpp>
5506
5507// #include <nlohmann/detail/input/input_adapters.hpp>
5508
5509
5510#include <array> // array
5511#include <cstddef> // size_t
5512#include <cstring> // strlen
5513#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5514#include <memory> // shared_ptr, make_shared, addressof
5515#include <numeric> // accumulate
5516#include <string> // string, char_traits
5517#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5518#include <utility> // pair, declval
5519
5520#ifndef JSON_NO_IO
5521 #include <cstdio> // FILE *
5522 #include <istream> // istream
5523#endif // JSON_NO_IO
5524
5525// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5526
5527// #include <nlohmann/detail/macro_scope.hpp>
5528
5529
5530namespace nlohmann
5531{
5532namespace detail
5533{
5536
5538// input adapters //
5540
5541#ifndef JSON_NO_IO
5547{
5548 public:
5549 using char_type = char;
5550
5552 explicit file_input_adapter(std::FILE* f) noexcept
5553 : m_file(f)
5554 {}
5555
5556 // make class move-only
5559 file_input_adapter& operator=(const file_input_adapter&) = delete;
5562
5563 std::char_traits<char>::int_type get_character() noexcept
5564 {
5565 return std::fgetc(m_file);
5566 }
5567
5568 private:
5570 std::FILE* m_file;
5571};
5572
5573
5584{
5585 public:
5586 using char_type = char;
5587
5589 {
5590 // clear stream flags; we use underlying streambuf I/O, do not
5591 // maintain ifstream flags, except eof
5592 if (is != nullptr)
5593 {
5594 is->clear(is->rdstate() & std::ios::eofbit);
5595 }
5596 }
5597
5598 explicit input_stream_adapter(std::istream& i)
5599 : is(&i), sb(i.rdbuf())
5600 {}
5601
5602 // delete because of pointer members
5606
5608 : is(rhs.is), sb(rhs.sb)
5609 {
5610 rhs.is = nullptr;
5611 rhs.sb = nullptr;
5612 }
5613
5614 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5615 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5616 // end up as the same value, e.g. 0xFFFFFFFF.
5617 std::char_traits<char>::int_type get_character()
5618 {
5619 auto res = sb->sbumpc();
5620 // set eof manually, as we don't use the istream interface.
5621 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5622 {
5623 is->clear(is->rdstate() | std::ios::eofbit);
5624 }
5625 return res;
5626 }
5627
5628 private:
5630 std::istream* is = nullptr;
5631 std::streambuf* sb = nullptr;
5632};
5633#endif // JSON_NO_IO
5634
5635// General-purpose iterator-based adapter. It might not be as fast as
5636// theoretically possible for some containers, but it is extremely versatile.
5637template<typename IteratorType>
5639{
5640 public:
5641 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5642
5643 iterator_input_adapter(IteratorType first, IteratorType last)
5644 : current(std::move(first)), end(std::move(last))
5645 {}
5646
5647 typename std::char_traits<char_type>::int_type get_character()
5648 {
5649 if (JSON_HEDLEY_LIKELY(current != end))
5650 {
5651 auto result = std::char_traits<char_type>::to_int_type(*current);
5652 std::advance(current, 1);
5653 return result;
5654 }
5655
5656 return std::char_traits<char_type>::eof();
5657 }
5658
5659 private:
5660 IteratorType current;
5661 IteratorType end;
5662
5663 template<typename BaseInputAdapter, size_t T>
5665
5666 bool empty() const
5667 {
5668 return current == end;
5669 }
5670};
5671
5672
5673template<typename BaseInputAdapter, size_t T>
5675
5676template<typename BaseInputAdapter>
5677struct wide_string_input_helper<BaseInputAdapter, 4>
5678{
5679 // UTF-32
5680 static void fill_buffer(BaseInputAdapter& input,
5681 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5682 size_t& utf8_bytes_index,
5683 size_t& utf8_bytes_filled)
5684 {
5685 utf8_bytes_index = 0;
5686
5687 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5688 {
5689 utf8_bytes[0] = std::char_traits<char>::eof();
5690 utf8_bytes_filled = 1;
5691 }
5692 else
5693 {
5694 // get the current character
5695 const auto wc = input.get_character();
5696
5697 // UTF-32 to UTF-8 encoding
5698 if (wc < 0x80)
5699 {
5700 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5701 utf8_bytes_filled = 1;
5702 }
5703 else if (wc <= 0x7FF)
5704 {
5705 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5706 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5707 utf8_bytes_filled = 2;
5708 }
5709 else if (wc <= 0xFFFF)
5710 {
5711 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5712 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5713 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5714 utf8_bytes_filled = 3;
5715 }
5716 else if (wc <= 0x10FFFF)
5717 {
5718 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5719 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5720 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5721 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5722 utf8_bytes_filled = 4;
5723 }
5724 else
5725 {
5726 // unknown character
5727 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5728 utf8_bytes_filled = 1;
5729 }
5730 }
5731 }
5732};
5733
5734template<typename BaseInputAdapter>
5735struct wide_string_input_helper<BaseInputAdapter, 2>
5736{
5737 // UTF-16
5738 static void fill_buffer(BaseInputAdapter& input,
5739 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5740 size_t& utf8_bytes_index,
5741 size_t& utf8_bytes_filled)
5742 {
5743 utf8_bytes_index = 0;
5744
5745 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5746 {
5747 utf8_bytes[0] = std::char_traits<char>::eof();
5748 utf8_bytes_filled = 1;
5749 }
5750 else
5751 {
5752 // get the current character
5753 const auto wc = input.get_character();
5754
5755 // UTF-16 to UTF-8 encoding
5756 if (wc < 0x80)
5757 {
5758 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5759 utf8_bytes_filled = 1;
5760 }
5761 else if (wc <= 0x7FF)
5762 {
5763 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5764 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5765 utf8_bytes_filled = 2;
5766 }
5767 else if (0xD800 > wc || wc >= 0xE000)
5768 {
5769 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5770 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5771 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5772 utf8_bytes_filled = 3;
5773 }
5774 else
5775 {
5776 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5777 {
5778 const auto wc2 = static_cast<unsigned int>(input.get_character());
5779 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5780 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5781 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5782 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5783 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5784 utf8_bytes_filled = 4;
5785 }
5786 else
5787 {
5788 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5789 utf8_bytes_filled = 1;
5790 }
5791 }
5792 }
5793 }
5794};
5795
5796// Wraps another input apdater to convert wide character types into individual bytes.
5797template<typename BaseInputAdapter, typename WideCharType>
5799{
5800 public:
5801 using char_type = char;
5802
5803 wide_string_input_adapter(BaseInputAdapter base)
5804 : base_adapter(base) {}
5805
5806 typename std::char_traits<char>::int_type get_character() noexcept
5807 {
5808 // check if buffer needs to be filled
5809 if (utf8_bytes_index == utf8_bytes_filled)
5810 {
5811 fill_buffer<sizeof(WideCharType)>();
5812
5813 JSON_ASSERT(utf8_bytes_filled > 0);
5814 JSON_ASSERT(utf8_bytes_index == 0);
5815 }
5816
5817 // use buffer
5818 JSON_ASSERT(utf8_bytes_filled > 0);
5819 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5820 return utf8_bytes[utf8_bytes_index++];
5821 }
5822
5823 private:
5824 BaseInputAdapter base_adapter;
5825
5826 template<size_t T>
5827 void fill_buffer()
5828 {
5829 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5830 }
5831
5833 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5834
5836 std::size_t utf8_bytes_index = 0;
5838 std::size_t utf8_bytes_filled = 0;
5839};
5840
5841
5842template<typename IteratorType, typename Enable = void>
5844{
5845 using iterator_type = IteratorType;
5846 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5848
5849 static adapter_type create(IteratorType first, IteratorType last)
5850 {
5851 return adapter_type(std::move(first), std::move(last));
5852 }
5853};
5854
5855template<typename T>
5857{
5858 using value_type = typename std::iterator_traits<T>::value_type;
5859 enum
5860 {
5861 value = sizeof(value_type) > 1
5862 };
5863};
5864
5865template<typename IteratorType>
5867{
5868 using iterator_type = IteratorType;
5869 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5872
5873 static adapter_type create(IteratorType first, IteratorType last)
5874 {
5875 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5876 }
5877};
5878
5879// General purpose iterator-based input
5880template<typename IteratorType>
5882{
5884 return factory_type::create(first, last);
5885}
5886
5887// Convenience shorthand from container to iterator
5888// Enables ADL on begin(container) and end(container)
5889// Encloses the using declarations in namespace for not to leak them to outside scope
5890
5891namespace container_input_adapter_factory_impl
5892{
5893
5894using std::begin;
5895using std::end;
5896
5897template<typename ContainerType, typename Enable = void>
5899
5900template<typename ContainerType>
5902 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5903 {
5904 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5905
5906 static adapter_type create(const ContainerType& container)
5907{
5908 return input_adapter(begin(container), end(container));
5909}
5910 };
5911
5912} // namespace container_input_adapter_factory_impl
5913
5914template<typename ContainerType>
5916{
5918}
5919
5920#ifndef JSON_NO_IO
5921// Special cases with fast paths
5922inline file_input_adapter input_adapter(std::FILE* file)
5923{
5924 return file_input_adapter(file);
5925}
5926
5927inline input_stream_adapter input_adapter(std::istream& stream)
5928{
5929 return input_stream_adapter(stream);
5930}
5931
5932inline input_stream_adapter input_adapter(std::istream&& stream)
5933{
5934 return input_stream_adapter(stream);
5935}
5936#endif // JSON_NO_IO
5937
5938using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5939
5940// Null-delimited strings, and the like.
5941template < typename CharT,
5942 typename std::enable_if <
5943 std::is_pointer<CharT>::value&&
5944 !std::is_array<CharT>::value&&
5945 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5946 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5947 int >::type = 0 >
5949{
5950 auto length = std::strlen(reinterpret_cast<const char*>(b));
5951 const auto* ptr = reinterpret_cast<const char*>(b);
5952 return input_adapter(ptr, ptr + length);
5953}
5954
5955template<typename T, std::size_t N>
5956auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5957{
5958 return input_adapter(array, array + N);
5959}
5960
5961// This class only handles inputs of input_buffer_adapter type.
5962// It's required so that expressions like {ptr, len} can be implicitly cast
5963// to the correct adapter.
5965{
5966 public:
5967 template < typename CharT,
5968 typename std::enable_if <
5969 std::is_pointer<CharT>::value&&
5970 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5971 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5972 int >::type = 0 >
5973 span_input_adapter(CharT b, std::size_t l)
5974 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5975
5976 template<class IteratorType,
5977 typename std::enable_if<
5978 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5979 int>::type = 0>
5980 span_input_adapter(IteratorType first, IteratorType last)
5981 : ia(input_adapter(first, last)) {}
5982
5984 {
5985 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5986 }
5987
5988 private:
5990};
5991} // namespace detail
5992} // namespace nlohmann
5993
5994// #include <nlohmann/detail/input/json_sax.hpp>
5995
5996
5997#include <cstddef>
5998#include <string> // string
5999#include <utility> // move
6000#include <vector> // vector
6001
6002// #include <nlohmann/detail/exceptions.hpp>
6003
6004// #include <nlohmann/detail/macro_scope.hpp>
6005
6006// #include <nlohmann/detail/string_concat.hpp>
6007
6008
6009namespace nlohmann
6010{
6011
6020template<typename BasicJsonType>
6022{
6023 using number_integer_t = typename BasicJsonType::number_integer_t;
6024 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6025 using number_float_t = typename BasicJsonType::number_float_t;
6026 using string_t = typename BasicJsonType::string_t;
6027 using binary_t = typename BasicJsonType::binary_t;
6028
6033 virtual bool null() = 0;
6034
6040 virtual bool boolean(bool val) = 0;
6041
6047 virtual bool number_integer(number_integer_t val) = 0;
6048
6054 virtual bool number_unsigned(number_unsigned_t val) = 0;
6055
6062 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6063
6070 virtual bool string(string_t& val) = 0;
6071
6078 virtual bool binary(binary_t& val) = 0;
6079
6086 virtual bool start_object(std::size_t elements) = 0;
6087
6094 virtual bool key(string_t& val) = 0;
6095
6100 virtual bool end_object() = 0;
6101
6108 virtual bool start_array(std::size_t elements) = 0;
6109
6114 virtual bool end_array() = 0;
6115
6123 virtual bool parse_error(std::size_t position,
6124 const std::string& last_token,
6125 const detail::exception& ex) = 0;
6126
6127 json_sax() = default;
6128 json_sax(const json_sax&) = default;
6129 json_sax(json_sax&&) noexcept = default;
6130 json_sax& operator=(const json_sax&) = default;
6131 json_sax& operator=(json_sax&&) noexcept = default;
6132 virtual ~json_sax() = default;
6133};
6134
6135
6136namespace detail
6137{
6151template<typename BasicJsonType>
6153{
6154 public:
6155 using number_integer_t = typename BasicJsonType::number_integer_t;
6156 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6157 using number_float_t = typename BasicJsonType::number_float_t;
6158 using string_t = typename BasicJsonType::string_t;
6159 using binary_t = typename BasicJsonType::binary_t;
6160
6166 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6167 : root(r), allow_exceptions(allow_exceptions_)
6168 {}
6169
6170 // make class move-only
6172 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6174 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6176
6177 bool null()
6178 {
6179 handle_value(nullptr);
6180 return true;
6181 }
6182
6183 bool boolean(bool val)
6184 {
6185 handle_value(val);
6186 return true;
6187 }
6188
6190 {
6191 handle_value(val);
6192 return true;
6193 }
6194
6196 {
6197 handle_value(val);
6198 return true;
6199 }
6200
6201 bool number_float(number_float_t val, const string_t& /*unused*/)
6202 {
6203 handle_value(val);
6204 return true;
6205 }
6206
6207 bool string(string_t& val)
6208 {
6209 handle_value(val);
6210 return true;
6211 }
6212
6213 bool binary(binary_t& val)
6214 {
6215 handle_value(std::move(val));
6216 return true;
6217 }
6218
6219 bool start_object(std::size_t len)
6220 {
6221 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6222
6223 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6224 {
6225 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6226 }
6227
6228 return true;
6229 }
6230
6231 bool key(string_t& val)
6232 {
6233 // add null at given key and store the reference for later
6234 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6235 return true;
6236 }
6237
6239 {
6240 ref_stack.back()->set_parents();
6241 ref_stack.pop_back();
6242 return true;
6243 }
6244
6245 bool start_array(std::size_t len)
6246 {
6247 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6248
6249 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6250 {
6251 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6252 }
6253
6254 return true;
6255 }
6256
6258 {
6259 ref_stack.back()->set_parents();
6260 ref_stack.pop_back();
6261 return true;
6262 }
6263
6264 template<class Exception>
6265 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6266 const Exception& ex)
6267 {
6268 errored = true;
6269 static_cast<void>(ex);
6270 if (allow_exceptions)
6271 {
6272 JSON_THROW(ex);
6273 }
6274 return false;
6275 }
6276
6277 constexpr bool is_errored() const
6278 {
6279 return errored;
6280 }
6281
6282 private:
6289 template<typename Value>
6291 BasicJsonType* handle_value(Value&& v)
6292 {
6293 if (ref_stack.empty())
6294 {
6295 root = BasicJsonType(std::forward<Value>(v));
6296 return &root;
6297 }
6298
6299 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6300
6301 if (ref_stack.back()->is_array())
6302 {
6303 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6304 return &(ref_stack.back()->m_value.array->back());
6305 }
6306
6307 JSON_ASSERT(ref_stack.back()->is_object());
6308 JSON_ASSERT(object_element);
6309 *object_element = BasicJsonType(std::forward<Value>(v));
6310 return object_element;
6311 }
6312
6314 BasicJsonType& root;
6316 std::vector<BasicJsonType*> ref_stack {};
6318 BasicJsonType* object_element = nullptr;
6320 bool errored = false;
6322 const bool allow_exceptions = true;
6323};
6324
6325template<typename BasicJsonType>
6327{
6328 public:
6329 using number_integer_t = typename BasicJsonType::number_integer_t;
6330 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6331 using number_float_t = typename BasicJsonType::number_float_t;
6332 using string_t = typename BasicJsonType::string_t;
6333 using binary_t = typename BasicJsonType::binary_t;
6336
6338 const parser_callback_t cb,
6339 const bool allow_exceptions_ = true)
6340 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6341 {
6342 keep_stack.push_back(true);
6343 }
6344
6345 // make class move-only
6347 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6349 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6351
6352 bool null()
6353 {
6354 handle_value(nullptr);
6355 return true;
6356 }
6357
6358 bool boolean(bool val)
6359 {
6360 handle_value(val);
6361 return true;
6362 }
6363
6365 {
6366 handle_value(val);
6367 return true;
6368 }
6369
6371 {
6372 handle_value(val);
6373 return true;
6374 }
6375
6376 bool number_float(number_float_t val, const string_t& /*unused*/)
6377 {
6378 handle_value(val);
6379 return true;
6380 }
6381
6382 bool string(string_t& val)
6383 {
6384 handle_value(val);
6385 return true;
6386 }
6387
6388 bool binary(binary_t& val)
6389 {
6390 handle_value(std::move(val));
6391 return true;
6392 }
6393
6394 bool start_object(std::size_t len)
6395 {
6396 // check callback for object start
6397 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6398 keep_stack.push_back(keep);
6399
6400 auto val = handle_value(BasicJsonType::value_t::object, true);
6401 ref_stack.push_back(val.second);
6402
6403 // check object limit
6404 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6405 {
6406 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6407 }
6408
6409 return true;
6410 }
6411
6412 bool key(string_t& val)
6413 {
6414 BasicJsonType k = BasicJsonType(val);
6415
6416 // check callback for key
6417 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6418 key_keep_stack.push_back(keep);
6419
6420 // add discarded value at given key and store the reference for later
6421 if (keep && ref_stack.back())
6422 {
6423 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6424 }
6425
6426 return true;
6427 }
6428
6430 {
6431 if (ref_stack.back())
6432 {
6433 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6434 {
6435 // discard object
6436 *ref_stack.back() = discarded;
6437 }
6438 else
6439 {
6440 ref_stack.back()->set_parents();
6441 }
6442 }
6443
6444 JSON_ASSERT(!ref_stack.empty());
6445 JSON_ASSERT(!keep_stack.empty());
6446 ref_stack.pop_back();
6447 keep_stack.pop_back();
6448
6449 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6450 {
6451 // remove discarded value
6452 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6453 {
6454 if (it->is_discarded())
6455 {
6456 ref_stack.back()->erase(it);
6457 break;
6458 }
6459 }
6460 }
6461
6462 return true;
6463 }
6464
6465 bool start_array(std::size_t len)
6466 {
6467 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6468 keep_stack.push_back(keep);
6469
6470 auto val = handle_value(BasicJsonType::value_t::array, true);
6471 ref_stack.push_back(val.second);
6472
6473 // check array limit
6474 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6475 {
6476 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6477 }
6478
6479 return true;
6480 }
6481
6483 {
6484 bool keep = true;
6485
6486 if (ref_stack.back())
6487 {
6488 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6489 if (keep)
6490 {
6491 ref_stack.back()->set_parents();
6492 }
6493 else
6494 {
6495 // discard array
6496 *ref_stack.back() = discarded;
6497 }
6498 }
6499
6500 JSON_ASSERT(!ref_stack.empty());
6501 JSON_ASSERT(!keep_stack.empty());
6502 ref_stack.pop_back();
6503 keep_stack.pop_back();
6504
6505 // remove discarded value
6506 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6507 {
6508 ref_stack.back()->m_value.array->pop_back();
6509 }
6510
6511 return true;
6512 }
6513
6514 template<class Exception>
6515 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6516 const Exception& ex)
6517 {
6518 errored = true;
6519 static_cast<void>(ex);
6520 if (allow_exceptions)
6521 {
6522 JSON_THROW(ex);
6523 }
6524 return false;
6525 }
6526
6527 constexpr bool is_errored() const
6528 {
6529 return errored;
6530 }
6531
6532 private:
6548 template<typename Value>
6549 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6550 {
6551 JSON_ASSERT(!keep_stack.empty());
6552
6553 // do not handle this value if we know it would be added to a discarded
6554 // container
6555 if (!keep_stack.back())
6556 {
6557 return {false, nullptr};
6558 }
6559
6560 // create value
6561 auto value = BasicJsonType(std::forward<Value>(v));
6562
6563 // check callback
6564 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6565
6566 // do not handle this value if we just learnt it shall be discarded
6567 if (!keep)
6568 {
6569 return {false, nullptr};
6570 }
6571
6572 if (ref_stack.empty())
6573 {
6574 root = std::move(value);
6575 return {true, &root};
6576 }
6577
6578 // skip this value if we already decided to skip the parent
6579 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6580 if (!ref_stack.back())
6581 {
6582 return {false, nullptr};
6583 }
6584
6585 // we now only expect arrays and objects
6586 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6587
6588 // array
6589 if (ref_stack.back()->is_array())
6590 {
6591 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6592 return {true, &(ref_stack.back()->m_value.array->back())};
6593 }
6594
6595 // object
6596 JSON_ASSERT(ref_stack.back()->is_object());
6597 // check if we should store an element for the current key
6598 JSON_ASSERT(!key_keep_stack.empty());
6599 const bool store_element = key_keep_stack.back();
6600 key_keep_stack.pop_back();
6601
6602 if (!store_element)
6603 {
6604 return {false, nullptr};
6605 }
6606
6607 JSON_ASSERT(object_element);
6608 *object_element = std::move(value);
6609 return {true, object_element};
6610 }
6611
6613 BasicJsonType& root;
6615 std::vector<BasicJsonType*> ref_stack {};
6617 std::vector<bool> keep_stack {};
6619 std::vector<bool> key_keep_stack {};
6621 BasicJsonType* object_element = nullptr;
6623 bool errored = false;
6625 const parser_callback_t callback = nullptr;
6627 const bool allow_exceptions = true;
6629 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6630};
6631
6632template<typename BasicJsonType>
6634{
6635 public:
6636 using number_integer_t = typename BasicJsonType::number_integer_t;
6637 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6638 using number_float_t = typename BasicJsonType::number_float_t;
6639 using string_t = typename BasicJsonType::string_t;
6640 using binary_t = typename BasicJsonType::binary_t;
6641
6642 bool null()
6643 {
6644 return true;
6645 }
6646
6647 bool boolean(bool /*unused*/)
6648 {
6649 return true;
6650 }
6651
6653 {
6654 return true;
6655 }
6656
6658 {
6659 return true;
6660 }
6661
6662 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6663 {
6664 return true;
6665 }
6666
6667 bool string(string_t& /*unused*/)
6668 {
6669 return true;
6670 }
6671
6672 bool binary(binary_t& /*unused*/)
6673 {
6674 return true;
6675 }
6676
6677 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6678 {
6679 return true;
6680 }
6681
6682 bool key(string_t& /*unused*/)
6683 {
6684 return true;
6685 }
6686
6688 {
6689 return true;
6690 }
6691
6692 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6693 {
6694 return true;
6695 }
6696
6698 {
6699 return true;
6700 }
6701
6702 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6703 {
6704 return false;
6705 }
6706};
6707} // namespace detail
6708
6709} // namespace nlohmann
6710
6711// #include <nlohmann/detail/input/lexer.hpp>
6712
6713
6714#include <array> // array
6715#include <clocale> // localeconv
6716#include <cstddef> // size_t
6717#include <cstdio> // snprintf
6718#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6719#include <initializer_list> // initializer_list
6720#include <string> // char_traits, string
6721#include <utility> // move
6722#include <vector> // vector
6723
6724// #include <nlohmann/detail/input/input_adapters.hpp>
6725
6726// #include <nlohmann/detail/input/position_t.hpp>
6727
6728// #include <nlohmann/detail/macro_scope.hpp>
6729
6730
6731namespace nlohmann
6732{
6733namespace detail
6734{
6736// lexer //
6738
6739template<typename BasicJsonType>
6741{
6742 public:
6744 enum class token_type
6745 {
6746 uninitialized,
6747 literal_true,
6748 literal_false,
6749 literal_null,
6750 value_string,
6751 value_unsigned,
6752 value_integer,
6753 value_float,
6754 begin_array,
6755 begin_object,
6756 end_array,
6757 end_object,
6758 name_separator,
6759 value_separator,
6760 parse_error,
6761 end_of_input,
6762 literal_or_value
6763 };
6764
6768 static const char* token_type_name(const token_type t) noexcept
6769 {
6770 switch (t)
6771 {
6773 return "<uninitialized>";
6775 return "true literal";
6777 return "false literal";
6779 return "null literal";
6781 return "string literal";
6785 return "number literal";
6787 return "'['";
6789 return "'{'";
6791 return "']'";
6793 return "'}'";
6795 return "':'";
6797 return "','";
6799 return "<parse error>";
6801 return "end of input";
6803 return "'[', '{', or a literal";
6804 // LCOV_EXCL_START
6805 default: // catch non-enum values
6806 return "unknown token";
6807 // LCOV_EXCL_STOP
6808 }
6809 }
6810};
6816template<typename BasicJsonType, typename InputAdapterType>
6817class lexer : public lexer_base<BasicJsonType>
6818{
6819 using number_integer_t = typename BasicJsonType::number_integer_t;
6820 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6821 using number_float_t = typename BasicJsonType::number_float_t;
6822 using string_t = typename BasicJsonType::string_t;
6823 using char_type = typename InputAdapterType::char_type;
6824 using char_int_type = typename std::char_traits<char_type>::int_type;
6825
6826 public:
6828
6829 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6830 : ia(std::move(adapter))
6831 , ignore_comments(ignore_comments_)
6832 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6833 {}
6834
6835 // delete because of pointer members
6836 lexer(const lexer&) = delete;
6837 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6838 lexer& operator=(lexer&) = delete;
6839 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6840 ~lexer() = default;
6841
6842 private:
6844 // locales
6846
6849 static char get_decimal_point() noexcept
6850 {
6851 const auto* loc = localeconv();
6852 JSON_ASSERT(loc != nullptr);
6853 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6854 }
6855
6857 // scan functions
6859
6875 int get_codepoint()
6876 {
6877 // this function only makes sense after reading `\u`
6878 JSON_ASSERT(current == 'u');
6879 int codepoint = 0;
6880
6881 const auto factors = { 12u, 8u, 4u, 0u };
6882 for (const auto factor : factors)
6883 {
6884 get();
6885
6886 if (current >= '0' && current <= '9')
6887 {
6888 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6889 }
6890 else if (current >= 'A' && current <= 'F')
6891 {
6892 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6893 }
6894 else if (current >= 'a' && current <= 'f')
6895 {
6896 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6897 }
6898 else
6899 {
6900 return -1;
6901 }
6902 }
6903
6904 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6905 return codepoint;
6906 }
6907
6923 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6924 {
6925 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6926 add(current);
6927
6928 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6929 {
6930 get();
6931 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6932 {
6933 add(current);
6934 }
6935 else
6936 {
6937 error_message = "invalid string: ill-formed UTF-8 byte";
6938 return false;
6939 }
6940 }
6941
6942 return true;
6943 }
6944
6960 token_type scan_string()
6961 {
6962 // reset token_buffer (ignore opening quote)
6963 reset();
6964
6965 // we entered the function by reading an open quote
6966 JSON_ASSERT(current == '\"');
6967
6968 while (true)
6969 {
6970 // get next character
6971 switch (get())
6972 {
6973 // end of file while parsing string
6974 case std::char_traits<char_type>::eof():
6975 {
6976 error_message = "invalid string: missing closing quote";
6977 return token_type::parse_error;
6978 }
6979
6980 // closing quote
6981 case '\"':
6982 {
6983 return token_type::value_string;
6984 }
6985
6986 // escapes
6987 case '\\':
6988 {
6989 switch (get())
6990 {
6991 // quotation mark
6992 case '\"':
6993 add('\"');
6994 break;
6995 // reverse solidus
6996 case '\\':
6997 add('\\');
6998 break;
6999 // solidus
7000 case '/':
7001 add('/');
7002 break;
7003 // backspace
7004 case 'b':
7005 add('\b');
7006 break;
7007 // form feed
7008 case 'f':
7009 add('\f');
7010 break;
7011 // line feed
7012 case 'n':
7013 add('\n');
7014 break;
7015 // carriage return
7016 case 'r':
7017 add('\r');
7018 break;
7019 // tab
7020 case 't':
7021 add('\t');
7022 break;
7023
7024 // unicode escapes
7025 case 'u':
7026 {
7027 const int codepoint1 = get_codepoint();
7028 int codepoint = codepoint1; // start with codepoint1
7029
7030 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7031 {
7032 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7033 return token_type::parse_error;
7034 }
7035
7036 // check if code point is a high surrogate
7037 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7038 {
7039 // expect next \uxxxx entry
7040 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7041 {
7042 const int codepoint2 = get_codepoint();
7043
7044 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7045 {
7046 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7047 return token_type::parse_error;
7048 }
7049
7050 // check if codepoint2 is a low surrogate
7051 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7052 {
7053 // overwrite codepoint
7054 codepoint = static_cast<int>(
7055 // high surrogate occupies the most significant 22 bits
7056 (static_cast<unsigned int>(codepoint1) << 10u)
7057 // low surrogate occupies the least significant 15 bits
7058 + static_cast<unsigned int>(codepoint2)
7059 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7060 // in the result, so we have to subtract with:
7061 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7062 - 0x35FDC00u);
7063 }
7064 else
7065 {
7066 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7067 return token_type::parse_error;
7068 }
7069 }
7070 else
7071 {
7072 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7073 return token_type::parse_error;
7074 }
7075 }
7076 else
7077 {
7078 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7079 {
7080 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7081 return token_type::parse_error;
7082 }
7083 }
7084
7085 // result of the above calculation yields a proper codepoint
7086 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7087
7088 // translate codepoint into bytes
7089 if (codepoint < 0x80)
7090 {
7091 // 1-byte characters: 0xxxxxxx (ASCII)
7092 add(static_cast<char_int_type>(codepoint));
7093 }
7094 else if (codepoint <= 0x7FF)
7095 {
7096 // 2-byte characters: 110xxxxx 10xxxxxx
7097 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7098 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7099 }
7100 else if (codepoint <= 0xFFFF)
7101 {
7102 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7103 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7104 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7105 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7106 }
7107 else
7108 {
7109 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7110 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7111 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7112 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7113 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7114 }
7115
7116 break;
7117 }
7118
7119 // other characters after escape
7120 default:
7121 error_message = "invalid string: forbidden character after backslash";
7122 return token_type::parse_error;
7123 }
7124
7125 break;
7126 }
7127
7128 // invalid control characters
7129 case 0x00:
7130 {
7131 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7132 return token_type::parse_error;
7133 }
7134
7135 case 0x01:
7136 {
7137 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7138 return token_type::parse_error;
7139 }
7140
7141 case 0x02:
7142 {
7143 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7144 return token_type::parse_error;
7145 }
7146
7147 case 0x03:
7148 {
7149 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7150 return token_type::parse_error;
7151 }
7152
7153 case 0x04:
7154 {
7155 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7156 return token_type::parse_error;
7157 }
7158
7159 case 0x05:
7160 {
7161 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7162 return token_type::parse_error;
7163 }
7164
7165 case 0x06:
7166 {
7167 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7168 return token_type::parse_error;
7169 }
7170
7171 case 0x07:
7172 {
7173 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7174 return token_type::parse_error;
7175 }
7176
7177 case 0x08:
7178 {
7179 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7180 return token_type::parse_error;
7181 }
7182
7183 case 0x09:
7184 {
7185 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7186 return token_type::parse_error;
7187 }
7188
7189 case 0x0A:
7190 {
7191 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7192 return token_type::parse_error;
7193 }
7194
7195 case 0x0B:
7196 {
7197 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7198 return token_type::parse_error;
7199 }
7200
7201 case 0x0C:
7202 {
7203 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7204 return token_type::parse_error;
7205 }
7206
7207 case 0x0D:
7208 {
7209 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7210 return token_type::parse_error;
7211 }
7212
7213 case 0x0E:
7214 {
7215 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7216 return token_type::parse_error;
7217 }
7218
7219 case 0x0F:
7220 {
7221 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7222 return token_type::parse_error;
7223 }
7224
7225 case 0x10:
7226 {
7227 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7228 return token_type::parse_error;
7229 }
7230
7231 case 0x11:
7232 {
7233 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7234 return token_type::parse_error;
7235 }
7236
7237 case 0x12:
7238 {
7239 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7240 return token_type::parse_error;
7241 }
7242
7243 case 0x13:
7244 {
7245 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7246 return token_type::parse_error;
7247 }
7248
7249 case 0x14:
7250 {
7251 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7252 return token_type::parse_error;
7253 }
7254
7255 case 0x15:
7256 {
7257 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7258 return token_type::parse_error;
7259 }
7260
7261 case 0x16:
7262 {
7263 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7264 return token_type::parse_error;
7265 }
7266
7267 case 0x17:
7268 {
7269 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7270 return token_type::parse_error;
7271 }
7272
7273 case 0x18:
7274 {
7275 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7276 return token_type::parse_error;
7277 }
7278
7279 case 0x19:
7280 {
7281 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7282 return token_type::parse_error;
7283 }
7284
7285 case 0x1A:
7286 {
7287 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7288 return token_type::parse_error;
7289 }
7290
7291 case 0x1B:
7292 {
7293 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7294 return token_type::parse_error;
7295 }
7296
7297 case 0x1C:
7298 {
7299 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7300 return token_type::parse_error;
7301 }
7302
7303 case 0x1D:
7304 {
7305 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7306 return token_type::parse_error;
7307 }
7308
7309 case 0x1E:
7310 {
7311 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7312 return token_type::parse_error;
7313 }
7314
7315 case 0x1F:
7316 {
7317 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7318 return token_type::parse_error;
7319 }
7320
7321 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7322 case 0x20:
7323 case 0x21:
7324 case 0x23:
7325 case 0x24:
7326 case 0x25:
7327 case 0x26:
7328 case 0x27:
7329 case 0x28:
7330 case 0x29:
7331 case 0x2A:
7332 case 0x2B:
7333 case 0x2C:
7334 case 0x2D:
7335 case 0x2E:
7336 case 0x2F:
7337 case 0x30:
7338 case 0x31:
7339 case 0x32:
7340 case 0x33:
7341 case 0x34:
7342 case 0x35:
7343 case 0x36:
7344 case 0x37:
7345 case 0x38:
7346 case 0x39:
7347 case 0x3A:
7348 case 0x3B:
7349 case 0x3C:
7350 case 0x3D:
7351 case 0x3E:
7352 case 0x3F:
7353 case 0x40:
7354 case 0x41:
7355 case 0x42:
7356 case 0x43:
7357 case 0x44:
7358 case 0x45:
7359 case 0x46:
7360 case 0x47:
7361 case 0x48:
7362 case 0x49:
7363 case 0x4A:
7364 case 0x4B:
7365 case 0x4C:
7366 case 0x4D:
7367 case 0x4E:
7368 case 0x4F:
7369 case 0x50:
7370 case 0x51:
7371 case 0x52:
7372 case 0x53:
7373 case 0x54:
7374 case 0x55:
7375 case 0x56:
7376 case 0x57:
7377 case 0x58:
7378 case 0x59:
7379 case 0x5A:
7380 case 0x5B:
7381 case 0x5D:
7382 case 0x5E:
7383 case 0x5F:
7384 case 0x60:
7385 case 0x61:
7386 case 0x62:
7387 case 0x63:
7388 case 0x64:
7389 case 0x65:
7390 case 0x66:
7391 case 0x67:
7392 case 0x68:
7393 case 0x69:
7394 case 0x6A:
7395 case 0x6B:
7396 case 0x6C:
7397 case 0x6D:
7398 case 0x6E:
7399 case 0x6F:
7400 case 0x70:
7401 case 0x71:
7402 case 0x72:
7403 case 0x73:
7404 case 0x74:
7405 case 0x75:
7406 case 0x76:
7407 case 0x77:
7408 case 0x78:
7409 case 0x79:
7410 case 0x7A:
7411 case 0x7B:
7412 case 0x7C:
7413 case 0x7D:
7414 case 0x7E:
7415 case 0x7F:
7416 {
7417 add(current);
7418 break;
7419 }
7420
7421 // U+0080..U+07FF: bytes C2..DF 80..BF
7422 case 0xC2:
7423 case 0xC3:
7424 case 0xC4:
7425 case 0xC5:
7426 case 0xC6:
7427 case 0xC7:
7428 case 0xC8:
7429 case 0xC9:
7430 case 0xCA:
7431 case 0xCB:
7432 case 0xCC:
7433 case 0xCD:
7434 case 0xCE:
7435 case 0xCF:
7436 case 0xD0:
7437 case 0xD1:
7438 case 0xD2:
7439 case 0xD3:
7440 case 0xD4:
7441 case 0xD5:
7442 case 0xD6:
7443 case 0xD7:
7444 case 0xD8:
7445 case 0xD9:
7446 case 0xDA:
7447 case 0xDB:
7448 case 0xDC:
7449 case 0xDD:
7450 case 0xDE:
7451 case 0xDF:
7452 {
7453 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7454 {
7455 return token_type::parse_error;
7456 }
7457 break;
7458 }
7459
7460 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7461 case 0xE0:
7462 {
7463 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7464 {
7465 return token_type::parse_error;
7466 }
7467 break;
7468 }
7469
7470 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7471 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7472 case 0xE1:
7473 case 0xE2:
7474 case 0xE3:
7475 case 0xE4:
7476 case 0xE5:
7477 case 0xE6:
7478 case 0xE7:
7479 case 0xE8:
7480 case 0xE9:
7481 case 0xEA:
7482 case 0xEB:
7483 case 0xEC:
7484 case 0xEE:
7485 case 0xEF:
7486 {
7487 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7488 {
7489 return token_type::parse_error;
7490 }
7491 break;
7492 }
7493
7494 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7495 case 0xED:
7496 {
7497 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7498 {
7499 return token_type::parse_error;
7500 }
7501 break;
7502 }
7503
7504 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7505 case 0xF0:
7506 {
7507 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7508 {
7509 return token_type::parse_error;
7510 }
7511 break;
7512 }
7513
7514 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7515 case 0xF1:
7516 case 0xF2:
7517 case 0xF3:
7518 {
7519 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7520 {
7521 return token_type::parse_error;
7522 }
7523 break;
7524 }
7525
7526 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7527 case 0xF4:
7528 {
7529 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7530 {
7531 return token_type::parse_error;
7532 }
7533 break;
7534 }
7535
7536 // remaining bytes (80..C1 and F5..FF) are ill-formed
7537 default:
7538 {
7539 error_message = "invalid string: ill-formed UTF-8 byte";
7540 return token_type::parse_error;
7541 }
7542 }
7543 }
7544 }
7545
7550 bool scan_comment()
7551 {
7552 switch (get())
7553 {
7554 // single-line comments skip input until a newline or EOF is read
7555 case '/':
7556 {
7557 while (true)
7558 {
7559 switch (get())
7560 {
7561 case '\n':
7562 case '\r':
7563 case std::char_traits<char_type>::eof():
7564 case '\0':
7565 return true;
7566
7567 default:
7568 break;
7569 }
7570 }
7571 }
7572
7573 // multi-line comments skip input until */ is read
7574 case '*':
7575 {
7576 while (true)
7577 {
7578 switch (get())
7579 {
7580 case std::char_traits<char_type>::eof():
7581 case '\0':
7582 {
7583 error_message = "invalid comment; missing closing '*/'";
7584 return false;
7585 }
7586
7587 case '*':
7588 {
7589 switch (get())
7590 {
7591 case '/':
7592 return true;
7593
7594 default:
7595 {
7596 unget();
7597 continue;
7598 }
7599 }
7600 }
7601
7602 default:
7603 continue;
7604 }
7605 }
7606 }
7607
7608 // unexpected character after reading '/'
7609 default:
7610 {
7611 error_message = "invalid comment; expecting '/' or '*' after '/'";
7612 return false;
7613 }
7614 }
7615 }
7616
7618 static void strtof(float& f, const char* str, char** endptr) noexcept
7619 {
7620 f = std::strtof(str, endptr);
7621 }
7622
7624 static void strtof(double& f, const char* str, char** endptr) noexcept
7625 {
7626 f = std::strtod(str, endptr);
7627 }
7628
7630 static void strtof(long double& f, const char* str, char** endptr) noexcept
7631 {
7632 f = std::strtold(str, endptr);
7633 }
7634
7675 token_type scan_number() // lgtm [cpp/use-of-goto]
7676 {
7677 // reset token_buffer to store the number's bytes
7678 reset();
7679
7680 // the type of the parsed number; initially set to unsigned; will be
7681 // changed if minus sign, decimal point or exponent is read
7682 token_type number_type = token_type::value_unsigned;
7683
7684 // state (init): we just found out we need to scan a number
7685 switch (current)
7686 {
7687 case '-':
7688 {
7689 add(current);
7690 goto scan_number_minus;
7691 }
7692
7693 case '0':
7694 {
7695 add(current);
7696 goto scan_number_zero;
7697 }
7698
7699 case '1':
7700 case '2':
7701 case '3':
7702 case '4':
7703 case '5':
7704 case '6':
7705 case '7':
7706 case '8':
7707 case '9':
7708 {
7709 add(current);
7710 goto scan_number_any1;
7711 }
7712
7713 // all other characters are rejected outside scan_number()
7714 default: // LCOV_EXCL_LINE
7715 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7716 }
7717
7718scan_number_minus:
7719 // state: we just parsed a leading minus sign
7720 number_type = token_type::value_integer;
7721 switch (get())
7722 {
7723 case '0':
7724 {
7725 add(current);
7726 goto scan_number_zero;
7727 }
7728
7729 case '1':
7730 case '2':
7731 case '3':
7732 case '4':
7733 case '5':
7734 case '6':
7735 case '7':
7736 case '8':
7737 case '9':
7738 {
7739 add(current);
7740 goto scan_number_any1;
7741 }
7742
7743 default:
7744 {
7745 error_message = "invalid number; expected digit after '-'";
7746 return token_type::parse_error;
7747 }
7748 }
7749
7750scan_number_zero:
7751 // state: we just parse a zero (maybe with a leading minus sign)
7752 switch (get())
7753 {
7754 case '.':
7755 {
7756 add(decimal_point_char);
7757 goto scan_number_decimal1;
7758 }
7759
7760 case 'e':
7761 case 'E':
7762 {
7763 add(current);
7764 goto scan_number_exponent;
7765 }
7766
7767 default:
7768 goto scan_number_done;
7769 }
7770
7771scan_number_any1:
7772 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7773 switch (get())
7774 {
7775 case '0':
7776 case '1':
7777 case '2':
7778 case '3':
7779 case '4':
7780 case '5':
7781 case '6':
7782 case '7':
7783 case '8':
7784 case '9':
7785 {
7786 add(current);
7787 goto scan_number_any1;
7788 }
7789
7790 case '.':
7791 {
7792 add(decimal_point_char);
7793 goto scan_number_decimal1;
7794 }
7795
7796 case 'e':
7797 case 'E':
7798 {
7799 add(current);
7800 goto scan_number_exponent;
7801 }
7802
7803 default:
7804 goto scan_number_done;
7805 }
7806
7807scan_number_decimal1:
7808 // state: we just parsed a decimal point
7809 number_type = token_type::value_float;
7810 switch (get())
7811 {
7812 case '0':
7813 case '1':
7814 case '2':
7815 case '3':
7816 case '4':
7817 case '5':
7818 case '6':
7819 case '7':
7820 case '8':
7821 case '9':
7822 {
7823 add(current);
7824 goto scan_number_decimal2;
7825 }
7826
7827 default:
7828 {
7829 error_message = "invalid number; expected digit after '.'";
7830 return token_type::parse_error;
7831 }
7832 }
7833
7834scan_number_decimal2:
7835 // we just parsed at least one number after a decimal point
7836 switch (get())
7837 {
7838 case '0':
7839 case '1':
7840 case '2':
7841 case '3':
7842 case '4':
7843 case '5':
7844 case '6':
7845 case '7':
7846 case '8':
7847 case '9':
7848 {
7849 add(current);
7850 goto scan_number_decimal2;
7851 }
7852
7853 case 'e':
7854 case 'E':
7855 {
7856 add(current);
7857 goto scan_number_exponent;
7858 }
7859
7860 default:
7861 goto scan_number_done;
7862 }
7863
7864scan_number_exponent:
7865 // we just parsed an exponent
7866 number_type = token_type::value_float;
7867 switch (get())
7868 {
7869 case '+':
7870 case '-':
7871 {
7872 add(current);
7873 goto scan_number_sign;
7874 }
7875
7876 case '0':
7877 case '1':
7878 case '2':
7879 case '3':
7880 case '4':
7881 case '5':
7882 case '6':
7883 case '7':
7884 case '8':
7885 case '9':
7886 {
7887 add(current);
7888 goto scan_number_any2;
7889 }
7890
7891 default:
7892 {
7893 error_message =
7894 "invalid number; expected '+', '-', or digit after exponent";
7895 return token_type::parse_error;
7896 }
7897 }
7898
7899scan_number_sign:
7900 // we just parsed an exponent sign
7901 switch (get())
7902 {
7903 case '0':
7904 case '1':
7905 case '2':
7906 case '3':
7907 case '4':
7908 case '5':
7909 case '6':
7910 case '7':
7911 case '8':
7912 case '9':
7913 {
7914 add(current);
7915 goto scan_number_any2;
7916 }
7917
7918 default:
7919 {
7920 error_message = "invalid number; expected digit after exponent sign";
7921 return token_type::parse_error;
7922 }
7923 }
7924
7925scan_number_any2:
7926 // we just parsed a number after the exponent or exponent sign
7927 switch (get())
7928 {
7929 case '0':
7930 case '1':
7931 case '2':
7932 case '3':
7933 case '4':
7934 case '5':
7935 case '6':
7936 case '7':
7937 case '8':
7938 case '9':
7939 {
7940 add(current);
7941 goto scan_number_any2;
7942 }
7943
7944 default:
7945 goto scan_number_done;
7946 }
7947
7948scan_number_done:
7949 // unget the character after the number (we only read it to know that
7950 // we are done scanning a number)
7951 unget();
7952
7953 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7954 errno = 0;
7955
7956 // try to parse integers first and fall back to floats
7957 if (number_type == token_type::value_unsigned)
7958 {
7959 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7960
7961 // we checked the number format before
7962 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7963
7964 if (errno == 0)
7965 {
7966 value_unsigned = static_cast<number_unsigned_t>(x);
7967 if (value_unsigned == x)
7968 {
7969 return token_type::value_unsigned;
7970 }
7971 }
7972 }
7973 else if (number_type == token_type::value_integer)
7974 {
7975 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7976
7977 // we checked the number format before
7978 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7979
7980 if (errno == 0)
7981 {
7982 value_integer = static_cast<number_integer_t>(x);
7983 if (value_integer == x)
7984 {
7985 return token_type::value_integer;
7986 }
7987 }
7988 }
7989
7990 // this code is reached if we parse a floating-point number or if an
7991 // integer conversion above failed
7992 strtof(value_float, token_buffer.data(), &endptr);
7993
7994 // we checked the number format before
7995 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7996
7997 return token_type::value_float;
7998 }
7999
8006 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8007 token_type return_type)
8008 {
8009 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8010 for (std::size_t i = 1; i < length; ++i)
8011 {
8012 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8013 {
8014 error_message = "invalid literal";
8015 return token_type::parse_error;
8016 }
8017 }
8018 return return_type;
8019 }
8020
8022 // input management
8024
8026 void reset() noexcept
8027 {
8028 token_buffer.clear();
8029 token_string.clear();
8030 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8031 }
8032
8033 /*
8034 @brief get next character from the input
8035
8036 This function provides the interface to the used input adapter. It does
8037 not throw in case the input reached EOF, but returns a
8038 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8039 for use in error messages.
8040
8041 @return character read from the input
8042 */
8043 char_int_type get()
8044 {
8045 ++position.chars_read_total;
8046 ++position.chars_read_current_line;
8047
8048 if (next_unget)
8049 {
8050 // just reset the next_unget variable and work with current
8051 next_unget = false;
8052 }
8053 else
8054 {
8055 current = ia.get_character();
8056 }
8057
8058 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8059 {
8060 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8061 }
8062
8063 if (current == '\n')
8064 {
8065 ++position.lines_read;
8066 position.chars_read_current_line = 0;
8067 }
8068
8069 return current;
8070 }
8071
8080 void unget()
8081 {
8082 next_unget = true;
8083
8084 --position.chars_read_total;
8085
8086 // in case we "unget" a newline, we have to also decrement the lines_read
8087 if (position.chars_read_current_line == 0)
8088 {
8089 if (position.lines_read > 0)
8090 {
8091 --position.lines_read;
8092 }
8093 }
8094 else
8095 {
8096 --position.chars_read_current_line;
8097 }
8098
8099 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8100 {
8101 JSON_ASSERT(!token_string.empty());
8102 token_string.pop_back();
8103 }
8104 }
8105
8107 void add(char_int_type c)
8108 {
8109 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8110 }
8111
8112 public:
8114 // value getters
8116
8118 constexpr number_integer_t get_number_integer() const noexcept
8119 {
8120 return value_integer;
8121 }
8122
8124 constexpr number_unsigned_t get_number_unsigned() const noexcept
8125 {
8126 return value_unsigned;
8127 }
8128
8130 constexpr number_float_t get_number_float() const noexcept
8131 {
8132 return value_float;
8133 }
8134
8136 string_t& get_string()
8137 {
8138 return token_buffer;
8139 }
8140
8142 // diagnostics
8144
8146 constexpr position_t get_position() const noexcept
8147 {
8148 return position;
8149 }
8150
8154 std::string get_token_string() const
8155 {
8156 // escape control characters
8157 std::string result;
8158 for (const auto c : token_string)
8159 {
8160 if (static_cast<unsigned char>(c) <= '\x1F')
8161 {
8162 // escape control characters
8163 std::array<char, 9> cs{{}};
8164 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8165 result += cs.data();
8166 }
8167 else
8168 {
8169 // add character as is
8170 result.push_back(static_cast<std::string::value_type>(c));
8171 }
8172 }
8173
8174 return result;
8175 }
8176
8179 constexpr const char* get_error_message() const noexcept
8180 {
8181 return error_message;
8182 }
8183
8185 // actual scanner
8187
8193 {
8194 if (get() == 0xEF)
8195 {
8196 // check if we completely parse the BOM
8197 return get() == 0xBB && get() == 0xBF;
8198 }
8199
8200 // the first character is not the beginning of the BOM; unget it to
8201 // process is later
8202 unget();
8203 return true;
8204 }
8205
8207 {
8208 do
8209 {
8210 get();
8211 }
8212 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8213 }
8214
8216 {
8217 // initially, skip the BOM
8218 if (position.chars_read_total == 0 && !skip_bom())
8219 {
8220 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8221 return token_type::parse_error;
8222 }
8223
8224 // read next character and ignore whitespace
8225 skip_whitespace();
8226
8227 // ignore comments
8228 while (ignore_comments && current == '/')
8229 {
8230 if (!scan_comment())
8231 {
8232 return token_type::parse_error;
8233 }
8234
8235 // skip following whitespace
8236 skip_whitespace();
8237 }
8238
8239 switch (current)
8240 {
8241 // structural characters
8242 case '[':
8243 return token_type::begin_array;
8244 case ']':
8245 return token_type::end_array;
8246 case '{':
8247 return token_type::begin_object;
8248 case '}':
8249 return token_type::end_object;
8250 case ':':
8251 return token_type::name_separator;
8252 case ',':
8253 return token_type::value_separator;
8254
8255 // literals
8256 case 't':
8257 {
8258 std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8259 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8260 }
8261 case 'f':
8262 {
8263 std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8264 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8265 }
8266 case 'n':
8267 {
8268 std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8269 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8270 }
8271
8272 // string
8273 case '\"':
8274 return scan_string();
8275
8276 // number
8277 case '-':
8278 case '0':
8279 case '1':
8280 case '2':
8281 case '3':
8282 case '4':
8283 case '5':
8284 case '6':
8285 case '7':
8286 case '8':
8287 case '9':
8288 return scan_number();
8289
8290 // end of input (the null byte is needed when parsing from
8291 // string literals)
8292 case '\0':
8293 case std::char_traits<char_type>::eof():
8294 return token_type::end_of_input;
8295
8296 // error
8297 default:
8298 error_message = "invalid literal";
8299 return token_type::parse_error;
8300 }
8301 }
8302
8303 private:
8305 InputAdapterType ia;
8306
8308 const bool ignore_comments = false;
8309
8311 char_int_type current = std::char_traits<char_type>::eof();
8312
8314 bool next_unget = false;
8315
8317 position_t position {};
8318
8320 std::vector<char_type> token_string {};
8321
8323 string_t token_buffer {};
8324
8326 const char* error_message = "";
8327
8328 // number values
8329 number_integer_t value_integer = 0;
8330 number_unsigned_t value_unsigned = 0;
8331 number_float_t value_float = 0;
8332
8334 const char_int_type decimal_point_char = '.';
8335};
8336} // namespace detail
8337} // namespace nlohmann
8338
8339// #include <nlohmann/detail/macro_scope.hpp>
8340
8341// #include <nlohmann/detail/meta/is_sax.hpp>
8342
8343
8344#include <cstdint> // size_t
8345#include <utility> // declval
8346#include <string> // string
8347
8348// #include <nlohmann/detail/meta/detected.hpp>
8349
8350// #include <nlohmann/detail/meta/type_traits.hpp>
8351
8352
8353namespace nlohmann
8354{
8355namespace detail
8356{
8357template<typename T>
8358using null_function_t = decltype(std::declval<T&>().null());
8359
8360template<typename T>
8362 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8363
8364template<typename T, typename Integer>
8366 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8367
8368template<typename T, typename Unsigned>
8370 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8371
8372template<typename T, typename Float, typename String>
8373using number_float_function_t = decltype(std::declval<T&>().number_float(
8374 std::declval<Float>(), std::declval<const String&>()));
8375
8376template<typename T, typename String>
8378 decltype(std::declval<T&>().string(std::declval<String&>()));
8379
8380template<typename T, typename Binary>
8382 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8383
8384template<typename T>
8386 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8387
8388template<typename T, typename String>
8390 decltype(std::declval<T&>().key(std::declval<String&>()));
8391
8392template<typename T>
8393using end_object_function_t = decltype(std::declval<T&>().end_object());
8394
8395template<typename T>
8397 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8398
8399template<typename T>
8400using end_array_function_t = decltype(std::declval<T&>().end_array());
8401
8402template<typename T, typename Exception>
8403using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8404 std::declval<std::size_t>(), std::declval<const std::string&>(),
8405 std::declval<const Exception&>()));
8406
8407template<typename SAX, typename BasicJsonType>
8409{
8410 private:
8412 "BasicJsonType must be of type basic_json<...>");
8413
8414 using number_integer_t = typename BasicJsonType::number_integer_t;
8415 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8416 using number_float_t = typename BasicJsonType::number_float_t;
8417 using string_t = typename BasicJsonType::string_t;
8418 using binary_t = typename BasicJsonType::binary_t;
8419 using exception_t = typename BasicJsonType::exception;
8420
8421 public:
8422 static constexpr bool value =
8436};
8437
8438template<typename SAX, typename BasicJsonType>
8440{
8441 private:
8443 "BasicJsonType must be of type basic_json<...>");
8444
8445 using number_integer_t = typename BasicJsonType::number_integer_t;
8446 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8447 using number_float_t = typename BasicJsonType::number_float_t;
8448 using string_t = typename BasicJsonType::string_t;
8449 using binary_t = typename BasicJsonType::binary_t;
8450 using exception_t = typename BasicJsonType::exception;
8451
8452 public:
8454 "Missing/invalid function: bool null()");
8456 "Missing/invalid function: bool boolean(bool)");
8458 "Missing/invalid function: bool boolean(bool)");
8459 static_assert(
8461 number_integer_t>::value,
8462 "Missing/invalid function: bool number_integer(number_integer_t)");
8463 static_assert(
8465 number_unsigned_t>::value,
8466 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8467 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8468 number_float_t, string_t>::value,
8469 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8470 static_assert(
8472 "Missing/invalid function: bool string(string_t&)");
8473 static_assert(
8475 "Missing/invalid function: bool binary(binary_t&)");
8477 "Missing/invalid function: bool start_object(std::size_t)");
8479 "Missing/invalid function: bool key(string_t&)");
8481 "Missing/invalid function: bool end_object()");
8483 "Missing/invalid function: bool start_array(std::size_t)");
8485 "Missing/invalid function: bool end_array()");
8486 static_assert(
8488 "Missing/invalid function: bool parse_error(std::size_t, const "
8489 "std::string&, const exception&)");
8490};
8491} // namespace detail
8492} // namespace nlohmann
8493
8494// #include <nlohmann/detail/meta/type_traits.hpp>
8495
8496// #include <nlohmann/detail/string_concat.hpp>
8497
8498// #include <nlohmann/detail/value_t.hpp>
8499
8500
8501namespace nlohmann
8502{
8503namespace detail
8504{
8505
8508{
8509 error,
8510 ignore,
8511 store
8512};
8513
8521static inline bool little_endianness(int num = 1) noexcept
8522{
8523 return *reinterpret_cast<char*>(&num) == 1;
8524}
8525
8526
8528// binary reader //
8530
8534template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8536{
8537 using number_integer_t = typename BasicJsonType::number_integer_t;
8538 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8539 using number_float_t = typename BasicJsonType::number_float_t;
8540 using string_t = typename BasicJsonType::string_t;
8541 using binary_t = typename BasicJsonType::binary_t;
8542 using json_sax_t = SAX;
8543 using char_type = typename InputAdapterType::char_type;
8544 using char_int_type = typename std::char_traits<char_type>::int_type;
8545
8546 public:
8552 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
8553 {
8555 }
8556
8557 // make class move-only
8559 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8561 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8562 ~binary_reader() = default;
8563
8573 bool sax_parse(const input_format_t format,
8574 json_sax_t* sax_,
8575 const bool strict = true,
8576 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8577 {
8578 sax = sax_;
8579 bool result = false;
8580
8581 switch (format)
8582 {
8584 result = parse_bson_internal();
8585 break;
8586
8588 result = parse_cbor_internal(true, tag_handler);
8589 break;
8590
8592 result = parse_msgpack_internal();
8593 break;
8594
8597 result = parse_ubjson_internal();
8598 break;
8599
8600 case input_format_t::json: // LCOV_EXCL_LINE
8601 default: // LCOV_EXCL_LINE
8602 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8603 }
8604
8605 // strict mode: next byte must be EOF
8606 if (result && strict)
8607 {
8608 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
8609 {
8610 get_ignore_noop();
8611 }
8612 else
8613 {
8614 get();
8615 }
8616
8617 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8618 {
8619 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
8620 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
8621 }
8622 }
8623
8624 return result;
8625 }
8626
8627 private:
8629 // BSON //
8631
8636 bool parse_bson_internal()
8637 {
8638 std::int32_t document_size{};
8639 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8640
8641 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
8642 {
8643 return false;
8644 }
8645
8646 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8647 {
8648 return false;
8649 }
8650
8651 return sax->end_object();
8652 }
8653
8661 bool get_bson_cstr(string_t& result)
8662 {
8663 auto out = std::back_inserter(result);
8664 while (true)
8665 {
8666 get();
8667 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8668 {
8669 return false;
8670 }
8671 if (current == 0x00)
8672 {
8673 return true;
8674 }
8675 *out++ = static_cast<typename string_t::value_type>(current);
8676 }
8677 }
8678
8690 template<typename NumberType>
8691 bool get_bson_string(const NumberType len, string_t& result)
8692 {
8693 if (JSON_HEDLEY_UNLIKELY(len < 1))
8694 {
8695 auto last_token = get_token_string();
8696 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8697 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
8698 }
8699
8700 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8701 }
8702
8712 template<typename NumberType>
8713 bool get_bson_binary(const NumberType len, binary_t& result)
8714 {
8715 if (JSON_HEDLEY_UNLIKELY(len < 0))
8716 {
8717 auto last_token = get_token_string();
8718 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8719 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
8720 }
8721
8722 // All BSON binary values have a subtype
8723 std::uint8_t subtype{};
8724 get_number<std::uint8_t>(input_format_t::bson, subtype);
8725 result.set_subtype(subtype);
8726
8727 return get_binary(input_format_t::bson, len, result);
8728 }
8729
8740 bool parse_bson_element_internal(const char_int_type element_type,
8741 const std::size_t element_type_parse_position)
8742 {
8743 switch (element_type)
8744 {
8745 case 0x01: // double
8746 {
8747 double number{};
8748 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8749 }
8750
8751 case 0x02: // string
8752 {
8753 std::int32_t len{};
8754 string_t value;
8755 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8756 }
8757
8758 case 0x03: // object
8759 {
8760 return parse_bson_internal();
8761 }
8762
8763 case 0x04: // array
8764 {
8765 return parse_bson_array();
8766 }
8767
8768 case 0x05: // binary
8769 {
8770 std::int32_t len{};
8771 binary_t value;
8772 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8773 }
8774
8775 case 0x08: // boolean
8776 {
8777 return sax->boolean(get() != 0);
8778 }
8779
8780 case 0x0A: // null
8781 {
8782 return sax->null();
8783 }
8784
8785 case 0x10: // int32
8786 {
8787 std::int32_t value{};
8788 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8789 }
8790
8791 case 0x12: // int64
8792 {
8793 std::int64_t value{};
8794 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8795 }
8796
8797 default: // anything else not supported (yet)
8798 {
8799 std::array<char, 3> cr{{}};
8800 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8801 std::string cr_str{cr.data()};
8802 return sax->parse_error(element_type_parse_position, cr_str,
8803 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
8804 }
8805 }
8806 }
8807
8820 bool parse_bson_element_list(const bool is_array)
8821 {
8822 string_t key;
8823
8824 while (auto element_type = get())
8825 {
8826 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8827 {
8828 return false;
8829 }
8830
8831 const std::size_t element_type_parse_position = chars_read;
8832 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8833 {
8834 return false;
8835 }
8836
8837 if (!is_array && !sax->key(key))
8838 {
8839 return false;
8840 }
8841
8842 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8843 {
8844 return false;
8845 }
8846
8847 // get_bson_cstr only appends
8848 key.clear();
8849 }
8850
8851 return true;
8852 }
8853
8858 bool parse_bson_array()
8859 {
8860 std::int32_t document_size{};
8861 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8862
8863 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
8864 {
8865 return false;
8866 }
8867
8868 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8869 {
8870 return false;
8871 }
8872
8873 return sax->end_array();
8874 }
8875
8877 // CBOR //
8879
8888 bool parse_cbor_internal(const bool get_char,
8889 const cbor_tag_handler_t tag_handler)
8890 {
8891 switch (get_char ? get() : current)
8892 {
8893 // EOF
8894 case std::char_traits<char_type>::eof():
8895 return unexpect_eof(input_format_t::cbor, "value");
8896
8897 // Integer 0x00..0x17 (0..23)
8898 case 0x00:
8899 case 0x01:
8900 case 0x02:
8901 case 0x03:
8902 case 0x04:
8903 case 0x05:
8904 case 0x06:
8905 case 0x07:
8906 case 0x08:
8907 case 0x09:
8908 case 0x0A:
8909 case 0x0B:
8910 case 0x0C:
8911 case 0x0D:
8912 case 0x0E:
8913 case 0x0F:
8914 case 0x10:
8915 case 0x11:
8916 case 0x12:
8917 case 0x13:
8918 case 0x14:
8919 case 0x15:
8920 case 0x16:
8921 case 0x17:
8922 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8923
8924 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8925 {
8926 std::uint8_t number{};
8927 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8928 }
8929
8930 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8931 {
8932 std::uint16_t number{};
8933 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8934 }
8935
8936 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8937 {
8938 std::uint32_t number{};
8939 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8940 }
8941
8942 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8943 {
8944 std::uint64_t number{};
8945 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8946 }
8947
8948 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8949 case 0x20:
8950 case 0x21:
8951 case 0x22:
8952 case 0x23:
8953 case 0x24:
8954 case 0x25:
8955 case 0x26:
8956 case 0x27:
8957 case 0x28:
8958 case 0x29:
8959 case 0x2A:
8960 case 0x2B:
8961 case 0x2C:
8962 case 0x2D:
8963 case 0x2E:
8964 case 0x2F:
8965 case 0x30:
8966 case 0x31:
8967 case 0x32:
8968 case 0x33:
8969 case 0x34:
8970 case 0x35:
8971 case 0x36:
8972 case 0x37:
8973 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8974
8975 case 0x38: // Negative integer (one-byte uint8_t follows)
8976 {
8977 std::uint8_t number{};
8978 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8979 }
8980
8981 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8982 {
8983 std::uint16_t number{};
8984 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8985 }
8986
8987 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8988 {
8989 std::uint32_t number{};
8990 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8991 }
8992
8993 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8994 {
8995 std::uint64_t number{};
8996 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8997 - static_cast<number_integer_t>(number));
8998 }
8999
9000 // Binary data (0x00..0x17 bytes follow)
9001 case 0x40:
9002 case 0x41:
9003 case 0x42:
9004 case 0x43:
9005 case 0x44:
9006 case 0x45:
9007 case 0x46:
9008 case 0x47:
9009 case 0x48:
9010 case 0x49:
9011 case 0x4A:
9012 case 0x4B:
9013 case 0x4C:
9014 case 0x4D:
9015 case 0x4E:
9016 case 0x4F:
9017 case 0x50:
9018 case 0x51:
9019 case 0x52:
9020 case 0x53:
9021 case 0x54:
9022 case 0x55:
9023 case 0x56:
9024 case 0x57:
9025 case 0x58: // Binary data (one-byte uint8_t for n follows)
9026 case 0x59: // Binary data (two-byte uint16_t for n follow)
9027 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9028 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9029 case 0x5F: // Binary data (indefinite length)
9030 {
9031 binary_t b;
9032 return get_cbor_binary(b) && sax->binary(b);
9033 }
9034
9035 // UTF-8 string (0x00..0x17 bytes follow)
9036 case 0x60:
9037 case 0x61:
9038 case 0x62:
9039 case 0x63:
9040 case 0x64:
9041 case 0x65:
9042 case 0x66:
9043 case 0x67:
9044 case 0x68:
9045 case 0x69:
9046 case 0x6A:
9047 case 0x6B:
9048 case 0x6C:
9049 case 0x6D:
9050 case 0x6E:
9051 case 0x6F:
9052 case 0x70:
9053 case 0x71:
9054 case 0x72:
9055 case 0x73:
9056 case 0x74:
9057 case 0x75:
9058 case 0x76:
9059 case 0x77:
9060 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9061 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9062 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9063 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9064 case 0x7F: // UTF-8 string (indefinite length)
9065 {
9066 string_t s;
9067 return get_cbor_string(s) && sax->string(s);
9068 }
9069
9070 // array (0x00..0x17 data items follow)
9071 case 0x80:
9072 case 0x81:
9073 case 0x82:
9074 case 0x83:
9075 case 0x84:
9076 case 0x85:
9077 case 0x86:
9078 case 0x87:
9079 case 0x88:
9080 case 0x89:
9081 case 0x8A:
9082 case 0x8B:
9083 case 0x8C:
9084 case 0x8D:
9085 case 0x8E:
9086 case 0x8F:
9087 case 0x90:
9088 case 0x91:
9089 case 0x92:
9090 case 0x93:
9091 case 0x94:
9092 case 0x95:
9093 case 0x96:
9094 case 0x97:
9095 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9096
9097 case 0x98: // array (one-byte uint8_t for n follows)
9098 {
9099 std::uint8_t len{};
9100 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9101 }
9102
9103 case 0x99: // array (two-byte uint16_t for n follow)
9104 {
9105 std::uint16_t len{};
9106 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9107 }
9108
9109 case 0x9A: // array (four-byte uint32_t for n follow)
9110 {
9111 std::uint32_t len{};
9112 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9113 }
9114
9115 case 0x9B: // array (eight-byte uint64_t for n follow)
9116 {
9117 std::uint64_t len{};
9118 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9119 }
9120
9121 case 0x9F: // array (indefinite length)
9122 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9123
9124 // map (0x00..0x17 pairs of data items follow)
9125 case 0xA0:
9126 case 0xA1:
9127 case 0xA2:
9128 case 0xA3:
9129 case 0xA4:
9130 case 0xA5:
9131 case 0xA6:
9132 case 0xA7:
9133 case 0xA8:
9134 case 0xA9:
9135 case 0xAA:
9136 case 0xAB:
9137 case 0xAC:
9138 case 0xAD:
9139 case 0xAE:
9140 case 0xAF:
9141 case 0xB0:
9142 case 0xB1:
9143 case 0xB2:
9144 case 0xB3:
9145 case 0xB4:
9146 case 0xB5:
9147 case 0xB6:
9148 case 0xB7:
9149 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9150
9151 case 0xB8: // map (one-byte uint8_t for n follows)
9152 {
9153 std::uint8_t len{};
9154 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9155 }
9156
9157 case 0xB9: // map (two-byte uint16_t for n follow)
9158 {
9159 std::uint16_t len{};
9160 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9161 }
9162
9163 case 0xBA: // map (four-byte uint32_t for n follow)
9164 {
9165 std::uint32_t len{};
9166 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9167 }
9168
9169 case 0xBB: // map (eight-byte uint64_t for n follow)
9170 {
9171 std::uint64_t len{};
9172 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9173 }
9174
9175 case 0xBF: // map (indefinite length)
9176 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9177
9178 case 0xC6: // tagged item
9179 case 0xC7:
9180 case 0xC8:
9181 case 0xC9:
9182 case 0xCA:
9183 case 0xCB:
9184 case 0xCC:
9185 case 0xCD:
9186 case 0xCE:
9187 case 0xCF:
9188 case 0xD0:
9189 case 0xD1:
9190 case 0xD2:
9191 case 0xD3:
9192 case 0xD4:
9193 case 0xD8: // tagged item (1 bytes follow)
9194 case 0xD9: // tagged item (2 bytes follow)
9195 case 0xDA: // tagged item (4 bytes follow)
9196 case 0xDB: // tagged item (8 bytes follow)
9197 {
9198 switch (tag_handler)
9199 {
9201 {
9202 auto last_token = get_token_string();
9203 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9204 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9205 }
9206
9208 {
9209 // ignore binary subtype
9210 switch (current)
9211 {
9212 case 0xD8:
9213 {
9214 std::uint8_t subtype_to_ignore{};
9215 get_number(input_format_t::cbor, subtype_to_ignore);
9216 break;
9217 }
9218 case 0xD9:
9219 {
9220 std::uint16_t subtype_to_ignore{};
9221 get_number(input_format_t::cbor, subtype_to_ignore);
9222 break;
9223 }
9224 case 0xDA:
9225 {
9226 std::uint32_t subtype_to_ignore{};
9227 get_number(input_format_t::cbor, subtype_to_ignore);
9228 break;
9229 }
9230 case 0xDB:
9231 {
9232 std::uint64_t subtype_to_ignore{};
9233 get_number(input_format_t::cbor, subtype_to_ignore);
9234 break;
9235 }
9236 default:
9237 break;
9238 }
9239 return parse_cbor_internal(true, tag_handler);
9240 }
9241
9243 {
9244 binary_t b;
9245 // use binary subtype and store in binary container
9246 switch (current)
9247 {
9248 case 0xD8:
9249 {
9250 std::uint8_t subtype{};
9251 get_number(input_format_t::cbor, subtype);
9252 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9253 break;
9254 }
9255 case 0xD9:
9256 {
9257 std::uint16_t subtype{};
9258 get_number(input_format_t::cbor, subtype);
9259 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9260 break;
9261 }
9262 case 0xDA:
9263 {
9264 std::uint32_t subtype{};
9265 get_number(input_format_t::cbor, subtype);
9266 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9267 break;
9268 }
9269 case 0xDB:
9270 {
9271 std::uint64_t subtype{};
9272 get_number(input_format_t::cbor, subtype);
9273 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9274 break;
9275 }
9276 default:
9277 return parse_cbor_internal(true, tag_handler);
9278 }
9279 get();
9280 return get_cbor_binary(b) && sax->binary(b);
9281 }
9282
9283 default: // LCOV_EXCL_LINE
9284 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9285 return false; // LCOV_EXCL_LINE
9286 }
9287 }
9288
9289 case 0xF4: // false
9290 return sax->boolean(false);
9291
9292 case 0xF5: // true
9293 return sax->boolean(true);
9294
9295 case 0xF6: // null
9296 return sax->null();
9297
9298 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9299 {
9300 const auto byte1_raw = get();
9301 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9302 {
9303 return false;
9304 }
9305 const auto byte2_raw = get();
9306 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9307 {
9308 return false;
9309 }
9310
9311 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9312 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9313
9314 // code from RFC 7049, Appendix D, Figure 3:
9315 // As half-precision floating-point numbers were only added
9316 // to IEEE 754 in 2008, today's programming platforms often
9317 // still only have limited support for them. It is very
9318 // easy to include at least decoding support for them even
9319 // without such support. An example of a small decoder for
9320 // half-precision floating-point numbers in the C language
9321 // is shown in Fig. 3.
9322 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9323 const double val = [&half]
9324 {
9325 const int exp = (half >> 10u) & 0x1Fu;
9326 const unsigned int mant = half & 0x3FFu;
9327 JSON_ASSERT(0 <= exp&& exp <= 32);
9328 JSON_ASSERT(mant <= 1024);
9329 switch (exp)
9330 {
9331 case 0:
9332 return std::ldexp(mant, -24);
9333 case 31:
9334 return (mant == 0)
9335 ? std::numeric_limits<double>::infinity()
9336 : std::numeric_limits<double>::quiet_NaN();
9337 default:
9338 return std::ldexp(mant + 1024, exp - 25);
9339 }
9340 }();
9341 return sax->number_float((half & 0x8000u) != 0
9342 ? static_cast<number_float_t>(-val)
9343 : static_cast<number_float_t>(val), "");
9344 }
9345
9346 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9347 {
9348 float number{};
9349 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9350 }
9351
9352 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9353 {
9354 double number{};
9355 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9356 }
9357
9358 default: // anything else (0xFF is handled inside the other types)
9359 {
9360 auto last_token = get_token_string();
9361 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9362 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9363 }
9364 }
9365 }
9366
9378 bool get_cbor_string(string_t& result)
9379 {
9380 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9381 {
9382 return false;
9383 }
9384
9385 switch (current)
9386 {
9387 // UTF-8 string (0x00..0x17 bytes follow)
9388 case 0x60:
9389 case 0x61:
9390 case 0x62:
9391 case 0x63:
9392 case 0x64:
9393 case 0x65:
9394 case 0x66:
9395 case 0x67:
9396 case 0x68:
9397 case 0x69:
9398 case 0x6A:
9399 case 0x6B:
9400 case 0x6C:
9401 case 0x6D:
9402 case 0x6E:
9403 case 0x6F:
9404 case 0x70:
9405 case 0x71:
9406 case 0x72:
9407 case 0x73:
9408 case 0x74:
9409 case 0x75:
9410 case 0x76:
9411 case 0x77:
9412 {
9413 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9414 }
9415
9416 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9417 {
9418 std::uint8_t len{};
9419 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9420 }
9421
9422 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9423 {
9424 std::uint16_t len{};
9425 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9426 }
9427
9428 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9429 {
9430 std::uint32_t len{};
9431 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9432 }
9433
9434 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9435 {
9436 std::uint64_t len{};
9437 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9438 }
9439
9440 case 0x7F: // UTF-8 string (indefinite length)
9441 {
9442 while (get() != 0xFF)
9443 {
9444 string_t chunk;
9445 if (!get_cbor_string(chunk))
9446 {
9447 return false;
9448 }
9449 result.append(chunk);
9450 }
9451 return true;
9452 }
9453
9454 default:
9455 {
9456 auto last_token = get_token_string();
9457 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9458 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
9459 }
9460 }
9461 }
9462
9474 bool get_cbor_binary(binary_t& result)
9475 {
9476 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9477 {
9478 return false;
9479 }
9480
9481 switch (current)
9482 {
9483 // Binary data (0x00..0x17 bytes follow)
9484 case 0x40:
9485 case 0x41:
9486 case 0x42:
9487 case 0x43:
9488 case 0x44:
9489 case 0x45:
9490 case 0x46:
9491 case 0x47:
9492 case 0x48:
9493 case 0x49:
9494 case 0x4A:
9495 case 0x4B:
9496 case 0x4C:
9497 case 0x4D:
9498 case 0x4E:
9499 case 0x4F:
9500 case 0x50:
9501 case 0x51:
9502 case 0x52:
9503 case 0x53:
9504 case 0x54:
9505 case 0x55:
9506 case 0x56:
9507 case 0x57:
9508 {
9509 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9510 }
9511
9512 case 0x58: // Binary data (one-byte uint8_t for n follows)
9513 {
9514 std::uint8_t len{};
9515 return get_number(input_format_t::cbor, len) &&
9516 get_binary(input_format_t::cbor, len, result);
9517 }
9518
9519 case 0x59: // Binary data (two-byte uint16_t for n follow)
9520 {
9521 std::uint16_t len{};
9522 return get_number(input_format_t::cbor, len) &&
9523 get_binary(input_format_t::cbor, len, result);
9524 }
9525
9526 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9527 {
9528 std::uint32_t len{};
9529 return get_number(input_format_t::cbor, len) &&
9530 get_binary(input_format_t::cbor, len, result);
9531 }
9532
9533 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9534 {
9535 std::uint64_t len{};
9536 return get_number(input_format_t::cbor, len) &&
9537 get_binary(input_format_t::cbor, len, result);
9538 }
9539
9540 case 0x5F: // Binary data (indefinite length)
9541 {
9542 while (get() != 0xFF)
9543 {
9544 binary_t chunk;
9545 if (!get_cbor_binary(chunk))
9546 {
9547 return false;
9548 }
9549 result.insert(result.end(), chunk.begin(), chunk.end());
9550 }
9551 return true;
9552 }
9553
9554 default:
9555 {
9556 auto last_token = get_token_string();
9557 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9558 exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
9559 }
9560 }
9561 }
9562
9569 bool get_cbor_array(const std::size_t len,
9570 const cbor_tag_handler_t tag_handler)
9571 {
9572 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9573 {
9574 return false;
9575 }
9576
9577 if (len != static_cast<std::size_t>(-1))
9578 {
9579 for (std::size_t i = 0; i < len; ++i)
9580 {
9581 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9582 {
9583 return false;
9584 }
9585 }
9586 }
9587 else
9588 {
9589 while (get() != 0xFF)
9590 {
9591 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9592 {
9593 return false;
9594 }
9595 }
9596 }
9597
9598 return sax->end_array();
9599 }
9600
9607 bool get_cbor_object(const std::size_t len,
9608 const cbor_tag_handler_t tag_handler)
9609 {
9610 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9611 {
9612 return false;
9613 }
9614
9615 if (len != 0)
9616 {
9617 string_t key;
9618 if (len != static_cast<std::size_t>(-1))
9619 {
9620 for (std::size_t i = 0; i < len; ++i)
9621 {
9622 get();
9623 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9624 {
9625 return false;
9626 }
9627
9628 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9629 {
9630 return false;
9631 }
9632 key.clear();
9633 }
9634 }
9635 else
9636 {
9637 while (get() != 0xFF)
9638 {
9639 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9640 {
9641 return false;
9642 }
9643
9644 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9645 {
9646 return false;
9647 }
9648 key.clear();
9649 }
9650 }
9651 }
9652
9653 return sax->end_object();
9654 }
9655
9657 // MsgPack //
9659
9663 bool parse_msgpack_internal()
9664 {
9665 switch (get())
9666 {
9667 // EOF
9668 case std::char_traits<char_type>::eof():
9669 return unexpect_eof(input_format_t::msgpack, "value");
9670
9671 // positive fixint
9672 case 0x00:
9673 case 0x01:
9674 case 0x02:
9675 case 0x03:
9676 case 0x04:
9677 case 0x05:
9678 case 0x06:
9679 case 0x07:
9680 case 0x08:
9681 case 0x09:
9682 case 0x0A:
9683 case 0x0B:
9684 case 0x0C:
9685 case 0x0D:
9686 case 0x0E:
9687 case 0x0F:
9688 case 0x10:
9689 case 0x11:
9690 case 0x12:
9691 case 0x13:
9692 case 0x14:
9693 case 0x15:
9694 case 0x16:
9695 case 0x17:
9696 case 0x18:
9697 case 0x19:
9698 case 0x1A:
9699 case 0x1B:
9700 case 0x1C:
9701 case 0x1D:
9702 case 0x1E:
9703 case 0x1F:
9704 case 0x20:
9705 case 0x21:
9706 case 0x22:
9707 case 0x23:
9708 case 0x24:
9709 case 0x25:
9710 case 0x26:
9711 case 0x27:
9712 case 0x28:
9713 case 0x29:
9714 case 0x2A:
9715 case 0x2B:
9716 case 0x2C:
9717 case 0x2D:
9718 case 0x2E:
9719 case 0x2F:
9720 case 0x30:
9721 case 0x31:
9722 case 0x32:
9723 case 0x33:
9724 case 0x34:
9725 case 0x35:
9726 case 0x36:
9727 case 0x37:
9728 case 0x38:
9729 case 0x39:
9730 case 0x3A:
9731 case 0x3B:
9732 case 0x3C:
9733 case 0x3D:
9734 case 0x3E:
9735 case 0x3F:
9736 case 0x40:
9737 case 0x41:
9738 case 0x42:
9739 case 0x43:
9740 case 0x44:
9741 case 0x45:
9742 case 0x46:
9743 case 0x47:
9744 case 0x48:
9745 case 0x49:
9746 case 0x4A:
9747 case 0x4B:
9748 case 0x4C:
9749 case 0x4D:
9750 case 0x4E:
9751 case 0x4F:
9752 case 0x50:
9753 case 0x51:
9754 case 0x52:
9755 case 0x53:
9756 case 0x54:
9757 case 0x55:
9758 case 0x56:
9759 case 0x57:
9760 case 0x58:
9761 case 0x59:
9762 case 0x5A:
9763 case 0x5B:
9764 case 0x5C:
9765 case 0x5D:
9766 case 0x5E:
9767 case 0x5F:
9768 case 0x60:
9769 case 0x61:
9770 case 0x62:
9771 case 0x63:
9772 case 0x64:
9773 case 0x65:
9774 case 0x66:
9775 case 0x67:
9776 case 0x68:
9777 case 0x69:
9778 case 0x6A:
9779 case 0x6B:
9780 case 0x6C:
9781 case 0x6D:
9782 case 0x6E:
9783 case 0x6F:
9784 case 0x70:
9785 case 0x71:
9786 case 0x72:
9787 case 0x73:
9788 case 0x74:
9789 case 0x75:
9790 case 0x76:
9791 case 0x77:
9792 case 0x78:
9793 case 0x79:
9794 case 0x7A:
9795 case 0x7B:
9796 case 0x7C:
9797 case 0x7D:
9798 case 0x7E:
9799 case 0x7F:
9800 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9801
9802 // fixmap
9803 case 0x80:
9804 case 0x81:
9805 case 0x82:
9806 case 0x83:
9807 case 0x84:
9808 case 0x85:
9809 case 0x86:
9810 case 0x87:
9811 case 0x88:
9812 case 0x89:
9813 case 0x8A:
9814 case 0x8B:
9815 case 0x8C:
9816 case 0x8D:
9817 case 0x8E:
9818 case 0x8F:
9819 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9820
9821 // fixarray
9822 case 0x90:
9823 case 0x91:
9824 case 0x92:
9825 case 0x93:
9826 case 0x94:
9827 case 0x95:
9828 case 0x96:
9829 case 0x97:
9830 case 0x98:
9831 case 0x99:
9832 case 0x9A:
9833 case 0x9B:
9834 case 0x9C:
9835 case 0x9D:
9836 case 0x9E:
9837 case 0x9F:
9838 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9839
9840 // fixstr
9841 case 0xA0:
9842 case 0xA1:
9843 case 0xA2:
9844 case 0xA3:
9845 case 0xA4:
9846 case 0xA5:
9847 case 0xA6:
9848 case 0xA7:
9849 case 0xA8:
9850 case 0xA9:
9851 case 0xAA:
9852 case 0xAB:
9853 case 0xAC:
9854 case 0xAD:
9855 case 0xAE:
9856 case 0xAF:
9857 case 0xB0:
9858 case 0xB1:
9859 case 0xB2:
9860 case 0xB3:
9861 case 0xB4:
9862 case 0xB5:
9863 case 0xB6:
9864 case 0xB7:
9865 case 0xB8:
9866 case 0xB9:
9867 case 0xBA:
9868 case 0xBB:
9869 case 0xBC:
9870 case 0xBD:
9871 case 0xBE:
9872 case 0xBF:
9873 case 0xD9: // str 8
9874 case 0xDA: // str 16
9875 case 0xDB: // str 32
9876 {
9877 string_t s;
9878 return get_msgpack_string(s) && sax->string(s);
9879 }
9880
9881 case 0xC0: // nil
9882 return sax->null();
9883
9884 case 0xC2: // false
9885 return sax->boolean(false);
9886
9887 case 0xC3: // true
9888 return sax->boolean(true);
9889
9890 case 0xC4: // bin 8
9891 case 0xC5: // bin 16
9892 case 0xC6: // bin 32
9893 case 0xC7: // ext 8
9894 case 0xC8: // ext 16
9895 case 0xC9: // ext 32
9896 case 0xD4: // fixext 1
9897 case 0xD5: // fixext 2
9898 case 0xD6: // fixext 4
9899 case 0xD7: // fixext 8
9900 case 0xD8: // fixext 16
9901 {
9902 binary_t b;
9903 return get_msgpack_binary(b) && sax->binary(b);
9904 }
9905
9906 case 0xCA: // float 32
9907 {
9908 float number{};
9909 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9910 }
9911
9912 case 0xCB: // float 64
9913 {
9914 double number{};
9915 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9916 }
9917
9918 case 0xCC: // uint 8
9919 {
9920 std::uint8_t number{};
9921 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9922 }
9923
9924 case 0xCD: // uint 16
9925 {
9926 std::uint16_t number{};
9927 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9928 }
9929
9930 case 0xCE: // uint 32
9931 {
9932 std::uint32_t number{};
9933 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9934 }
9935
9936 case 0xCF: // uint 64
9937 {
9938 std::uint64_t number{};
9939 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9940 }
9941
9942 case 0xD0: // int 8
9943 {
9944 std::int8_t number{};
9945 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9946 }
9947
9948 case 0xD1: // int 16
9949 {
9950 std::int16_t number{};
9951 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9952 }
9953
9954 case 0xD2: // int 32
9955 {
9956 std::int32_t number{};
9957 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9958 }
9959
9960 case 0xD3: // int 64
9961 {
9962 std::int64_t number{};
9963 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9964 }
9965
9966 case 0xDC: // array 16
9967 {
9968 std::uint16_t len{};
9969 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9970 }
9971
9972 case 0xDD: // array 32
9973 {
9974 std::uint32_t len{};
9975 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9976 }
9977
9978 case 0xDE: // map 16
9979 {
9980 std::uint16_t len{};
9981 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9982 }
9983
9984 case 0xDF: // map 32
9985 {
9986 std::uint32_t len{};
9987 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9988 }
9989
9990 // negative fixint
9991 case 0xE0:
9992 case 0xE1:
9993 case 0xE2:
9994 case 0xE3:
9995 case 0xE4:
9996 case 0xE5:
9997 case 0xE6:
9998 case 0xE7:
9999 case 0xE8:
10000 case 0xE9:
10001 case 0xEA:
10002 case 0xEB:
10003 case 0xEC:
10004 case 0xED:
10005 case 0xEE:
10006 case 0xEF:
10007 case 0xF0:
10008 case 0xF1:
10009 case 0xF2:
10010 case 0xF3:
10011 case 0xF4:
10012 case 0xF5:
10013 case 0xF6:
10014 case 0xF7:
10015 case 0xF8:
10016 case 0xF9:
10017 case 0xFA:
10018 case 0xFB:
10019 case 0xFC:
10020 case 0xFD:
10021 case 0xFE:
10022 case 0xFF:
10023 return sax->number_integer(static_cast<std::int8_t>(current));
10024
10025 default: // anything else
10026 {
10027 auto last_token = get_token_string();
10028 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10029 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10030 }
10031 }
10032 }
10033
10044 bool get_msgpack_string(string_t& result)
10045 {
10046 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10047 {
10048 return false;
10049 }
10050
10051 switch (current)
10052 {
10053 // fixstr
10054 case 0xA0:
10055 case 0xA1:
10056 case 0xA2:
10057 case 0xA3:
10058 case 0xA4:
10059 case 0xA5:
10060 case 0xA6:
10061 case 0xA7:
10062 case 0xA8:
10063 case 0xA9:
10064 case 0xAA:
10065 case 0xAB:
10066 case 0xAC:
10067 case 0xAD:
10068 case 0xAE:
10069 case 0xAF:
10070 case 0xB0:
10071 case 0xB1:
10072 case 0xB2:
10073 case 0xB3:
10074 case 0xB4:
10075 case 0xB5:
10076 case 0xB6:
10077 case 0xB7:
10078 case 0xB8:
10079 case 0xB9:
10080 case 0xBA:
10081 case 0xBB:
10082 case 0xBC:
10083 case 0xBD:
10084 case 0xBE:
10085 case 0xBF:
10086 {
10087 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10088 }
10089
10090 case 0xD9: // str 8
10091 {
10092 std::uint8_t len{};
10093 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10094 }
10095
10096 case 0xDA: // str 16
10097 {
10098 std::uint16_t len{};
10099 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10100 }
10101
10102 case 0xDB: // str 32
10103 {
10104 std::uint32_t len{};
10105 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10106 }
10107
10108 default:
10109 {
10110 auto last_token = get_token_string();
10111 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10112 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10113 }
10114 }
10115 }
10116
10127 bool get_msgpack_binary(binary_t& result)
10128 {
10129 // helper function to set the subtype
10130 auto assign_and_return_true = [&result](std::int8_t subtype)
10131 {
10132 result.set_subtype(static_cast<std::uint8_t>(subtype));
10133 return true;
10134 };
10135
10136 switch (current)
10137 {
10138 case 0xC4: // bin 8
10139 {
10140 std::uint8_t len{};
10141 return get_number(input_format_t::msgpack, len) &&
10142 get_binary(input_format_t::msgpack, len, result);
10143 }
10144
10145 case 0xC5: // bin 16
10146 {
10147 std::uint16_t len{};
10148 return get_number(input_format_t::msgpack, len) &&
10149 get_binary(input_format_t::msgpack, len, result);
10150 }
10151
10152 case 0xC6: // bin 32
10153 {
10154 std::uint32_t len{};
10155 return get_number(input_format_t::msgpack, len) &&
10156 get_binary(input_format_t::msgpack, len, result);
10157 }
10158
10159 case 0xC7: // ext 8
10160 {
10161 std::uint8_t len{};
10162 std::int8_t subtype{};
10163 return get_number(input_format_t::msgpack, len) &&
10164 get_number(input_format_t::msgpack, subtype) &&
10165 get_binary(input_format_t::msgpack, len, result) &&
10166 assign_and_return_true(subtype);
10167 }
10168
10169 case 0xC8: // ext 16
10170 {
10171 std::uint16_t len{};
10172 std::int8_t subtype{};
10173 return get_number(input_format_t::msgpack, len) &&
10174 get_number(input_format_t::msgpack, subtype) &&
10175 get_binary(input_format_t::msgpack, len, result) &&
10176 assign_and_return_true(subtype);
10177 }
10178
10179 case 0xC9: // ext 32
10180 {
10181 std::uint32_t len{};
10182 std::int8_t subtype{};
10183 return get_number(input_format_t::msgpack, len) &&
10184 get_number(input_format_t::msgpack, subtype) &&
10185 get_binary(input_format_t::msgpack, len, result) &&
10186 assign_and_return_true(subtype);
10187 }
10188
10189 case 0xD4: // fixext 1
10190 {
10191 std::int8_t subtype{};
10192 return get_number(input_format_t::msgpack, subtype) &&
10193 get_binary(input_format_t::msgpack, 1, result) &&
10194 assign_and_return_true(subtype);
10195 }
10196
10197 case 0xD5: // fixext 2
10198 {
10199 std::int8_t subtype{};
10200 return get_number(input_format_t::msgpack, subtype) &&
10201 get_binary(input_format_t::msgpack, 2, result) &&
10202 assign_and_return_true(subtype);
10203 }
10204
10205 case 0xD6: // fixext 4
10206 {
10207 std::int8_t subtype{};
10208 return get_number(input_format_t::msgpack, subtype) &&
10209 get_binary(input_format_t::msgpack, 4, result) &&
10210 assign_and_return_true(subtype);
10211 }
10212
10213 case 0xD7: // fixext 8
10214 {
10215 std::int8_t subtype{};
10216 return get_number(input_format_t::msgpack, subtype) &&
10217 get_binary(input_format_t::msgpack, 8, result) &&
10218 assign_and_return_true(subtype);
10219 }
10220
10221 case 0xD8: // fixext 16
10222 {
10223 std::int8_t subtype{};
10224 return get_number(input_format_t::msgpack, subtype) &&
10225 get_binary(input_format_t::msgpack, 16, result) &&
10226 assign_and_return_true(subtype);
10227 }
10228
10229 default: // LCOV_EXCL_LINE
10230 return false; // LCOV_EXCL_LINE
10231 }
10232 }
10233
10238 bool get_msgpack_array(const std::size_t len)
10239 {
10240 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10241 {
10242 return false;
10243 }
10244
10245 for (std::size_t i = 0; i < len; ++i)
10246 {
10247 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10248 {
10249 return false;
10250 }
10251 }
10252
10253 return sax->end_array();
10254 }
10255
10260 bool get_msgpack_object(const std::size_t len)
10261 {
10262 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10263 {
10264 return false;
10265 }
10266
10267 string_t key;
10268 for (std::size_t i = 0; i < len; ++i)
10269 {
10270 get();
10271 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10272 {
10273 return false;
10274 }
10275
10276 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10277 {
10278 return false;
10279 }
10280 key.clear();
10281 }
10282
10283 return sax->end_object();
10284 }
10285
10287 // UBJSON //
10289
10297 bool parse_ubjson_internal(const bool get_char = true)
10298 {
10299 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10300 }
10301
10316 bool get_ubjson_string(string_t& result, const bool get_char = true)
10317 {
10318 if (get_char)
10319 {
10320 get(); // TODO(niels): may we ignore N here?
10321 }
10322
10323 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10324 {
10325 return false;
10326 }
10327
10328 switch (current)
10329 {
10330 case 'U':
10331 {
10332 std::uint8_t len{};
10333 return get_number(input_format, len) && get_string(input_format, len, result);
10334 }
10335
10336 case 'i':
10337 {
10338 std::int8_t len{};
10339 return get_number(input_format, len) && get_string(input_format, len, result);
10340 }
10341
10342 case 'I':
10343 {
10344 std::int16_t len{};
10345 return get_number(input_format, len) && get_string(input_format, len, result);
10346 }
10347
10348 case 'l':
10349 {
10350 std::int32_t len{};
10351 return get_number(input_format, len) && get_string(input_format, len, result);
10352 }
10353
10354 case 'L':
10355 {
10356 std::int64_t len{};
10357 return get_number(input_format, len) && get_string(input_format, len, result);
10358 }
10359
10360 case 'u':
10361 {
10362 if (input_format != input_format_t::bjdata)
10363 {
10364 break;
10365 }
10366 std::uint16_t len{};
10367 return get_number(input_format, len) && get_string(input_format, len, result);
10368 }
10369
10370 case 'm':
10371 {
10372 if (input_format != input_format_t::bjdata)
10373 {
10374 break;
10375 }
10376 std::uint32_t len{};
10377 return get_number(input_format, len) && get_string(input_format, len, result);
10378 }
10379
10380 case 'M':
10381 {
10382 if (input_format != input_format_t::bjdata)
10383 {
10384 break;
10385 }
10386 std::uint64_t len{};
10387 return get_number(input_format, len) && get_string(input_format, len, result);
10388 }
10389
10390 default:
10391 break;
10392 }
10393 auto last_token = get_token_string();
10394 std::string message;
10395
10396 if (input_format != input_format_t::bjdata)
10397 {
10398 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
10399 }
10400 else
10401 {
10402 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
10403 }
10404 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
10405 }
10406
10411 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
10412 {
10413 std::pair<std::size_t, char_int_type> size_and_type;
10414 size_t dimlen = 0;
10415 bool is_ndarray = false;
10416
10417 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10418 {
10419 return false;
10420 }
10421
10422 if (size_and_type.first != string_t::npos)
10423 {
10424 if (size_and_type.second != 0)
10425 {
10426 if (size_and_type.second != 'N')
10427 {
10428 for (std::size_t i = 0; i < size_and_type.first; ++i)
10429 {
10430 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, is_ndarray, size_and_type.second)))
10431 {
10432 return false;
10433 }
10434 dim.push_back(dimlen);
10435 }
10436 }
10437 }
10438 else
10439 {
10440 for (std::size_t i = 0; i < size_and_type.first; ++i)
10441 {
10442 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, is_ndarray)))
10443 {
10444 return false;
10445 }
10446 dim.push_back(dimlen);
10447 }
10448 }
10449 }
10450 else
10451 {
10452 while (current != ']')
10453 {
10454 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, is_ndarray, current)))
10455 {
10456 return false;
10457 }
10458 dim.push_back(dimlen);
10459 get_ignore_noop();
10460 }
10461 }
10462 return true;
10463 }
10464
10469 bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
10470 {
10471 is_ndarray = false;
10472 if (prefix == 0)
10473 {
10474 prefix = get_ignore_noop();
10475 }
10476
10477 switch (prefix)
10478 {
10479 case 'U':
10480 {
10481 std::uint8_t number{};
10482 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10483 {
10484 return false;
10485 }
10486 result = static_cast<std::size_t>(number);
10487 return true;
10488 }
10489
10490 case 'i':
10491 {
10492 std::int8_t number{};
10493 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10494 {
10495 return false;
10496 }
10497 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10498 return true;
10499 }
10500
10501 case 'I':
10502 {
10503 std::int16_t number{};
10504 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10505 {
10506 return false;
10507 }
10508 result = static_cast<std::size_t>(number);
10509 return true;
10510 }
10511
10512 case 'l':
10513 {
10514 std::int32_t number{};
10515 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10516 {
10517 return false;
10518 }
10519 result = static_cast<std::size_t>(number);
10520 return true;
10521 }
10522
10523 case 'L':
10524 {
10525 std::int64_t number{};
10526 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10527 {
10528 return false;
10529 }
10530 result = static_cast<std::size_t>(number);
10531 return true;
10532 }
10533
10534 case 'u':
10535 {
10536 if (input_format != input_format_t::bjdata)
10537 {
10538 break;
10539 }
10540 std::uint16_t number{};
10541 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10542 {
10543 return false;
10544 }
10545 result = static_cast<std::size_t>(number);
10546 return true;
10547 }
10548
10549 case 'm':
10550 {
10551 if (input_format != input_format_t::bjdata)
10552 {
10553 break;
10554 }
10555 std::uint32_t number{};
10556 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10557 {
10558 return false;
10559 }
10560 result = static_cast<std::size_t>(number);
10561 return true;
10562 }
10563
10564 case 'M':
10565 {
10566 if (input_format != input_format_t::bjdata)
10567 {
10568 break;
10569 }
10570 std::uint64_t number{};
10571 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10572 {
10573 return false;
10574 }
10575 result = detail::conditional_static_cast<std::size_t>(number);
10576 return true;
10577 }
10578
10579 case '[':
10580 {
10581 if (input_format != input_format_t::bjdata)
10582 {
10583 break;
10584 }
10585 std::vector<size_t> dim;
10586 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
10587 {
10588 return false;
10589 }
10590 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
10591 {
10592 result = dim.at(dim.size() - 1);
10593 return true;
10594 }
10595 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
10596 {
10597 string_t key = "_ArraySize_";
10598 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
10599 {
10600 return false;
10601 }
10602 result = 1;
10603 for (auto i : dim)
10604 {
10605 result *= i;
10606 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(static_cast<number_integer_t>(i))))
10607 {
10608 return false;
10609 }
10610 }
10611 is_ndarray = true;
10612 return sax->end_array();
10613 }
10614 result = 0;
10615 return true;
10616 }
10617
10618 default:
10619 break;
10620 }
10621 auto last_token = get_token_string();
10622 std::string message;
10623
10624 if (input_format != input_format_t::bjdata)
10625 {
10626 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
10627 }
10628 else
10629 {
10630 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
10631 }
10632 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
10633 }
10634
10645 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10646 {
10647 bool is_ndarray = false;
10648 result.first = string_t::npos; // size
10649 result.second = 0; // type
10650
10651 get_ignore_noop();
10652
10653 if (current == '$')
10654 {
10655 std::vector<char_int_type> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
10656
10657 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10658 if (JSON_HEDLEY_UNLIKELY( input_format == input_format_t::bjdata && std::find(bjdx.begin(), bjdx.end(), result.second) != bjdx.end() ))
10659 {
10660 auto last_token = get_token_string();
10661 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10662 exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
10663 }
10664
10665 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
10666 {
10667 return false;
10668 }
10669
10670 get_ignore_noop();
10671 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10672 {
10673 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10674 {
10675 return false;
10676 }
10677 auto last_token = get_token_string();
10678 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10679 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
10680 }
10681
10682 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
10683 if (input_format == input_format_t::bjdata && is_ndarray)
10684 {
10685 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
10686 }
10687 return is_error;
10688 }
10689
10690 if (current == '#')
10691 {
10692 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
10693 if (input_format == input_format_t::bjdata && is_ndarray)
10694 {
10695 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
10696 }
10697 return is_error;
10698 }
10699
10700 return true;
10701 }
10702
10707 bool get_ubjson_value(const char_int_type prefix)
10708 {
10709 switch (prefix)
10710 {
10711 case std::char_traits<char_type>::eof(): // EOF
10712 return unexpect_eof(input_format, "value");
10713
10714 case 'T': // true
10715 return sax->boolean(true);
10716 case 'F': // false
10717 return sax->boolean(false);
10718
10719 case 'Z': // null
10720 return sax->null();
10721
10722 case 'U':
10723 {
10724 std::uint8_t number{};
10725 return get_number(input_format, number) && sax->number_unsigned(number);
10726 }
10727
10728 case 'i':
10729 {
10730 std::int8_t number{};
10731 return get_number(input_format, number) && sax->number_integer(number);
10732 }
10733
10734 case 'I':
10735 {
10736 std::int16_t number{};
10737 return get_number(input_format, number) && sax->number_integer(number);
10738 }
10739
10740 case 'l':
10741 {
10742 std::int32_t number{};
10743 return get_number(input_format, number) && sax->number_integer(number);
10744 }
10745
10746 case 'L':
10747 {
10748 std::int64_t number{};
10749 return get_number(input_format, number) && sax->number_integer(number);
10750 }
10751
10752 case 'u':
10753 {
10754 if (input_format != input_format_t::bjdata)
10755 {
10756 break;
10757 }
10758 std::uint16_t number{};
10759 return get_number(input_format, number) && sax->number_unsigned(number);
10760 }
10761
10762 case 'm':
10763 {
10764 if (input_format != input_format_t::bjdata)
10765 {
10766 break;
10767 }
10768 std::uint32_t number{};
10769 return get_number(input_format, number) && sax->number_unsigned(number);
10770 }
10771
10772 case 'M':
10773 {
10774 if (input_format != input_format_t::bjdata)
10775 {
10776 break;
10777 }
10778 std::uint64_t number{};
10779 return get_number(input_format, number) && sax->number_unsigned(number);
10780 }
10781
10782 case 'h':
10783 {
10784 if (input_format != input_format_t::bjdata)
10785 {
10786 break;
10787 }
10788 const auto byte1_raw = get();
10789 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
10790 {
10791 return false;
10792 }
10793 const auto byte2_raw = get();
10794 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
10795 {
10796 return false;
10797 }
10798
10799 const auto byte1 = static_cast<unsigned char>(byte1_raw);
10800 const auto byte2 = static_cast<unsigned char>(byte2_raw);
10801
10802 // code from RFC 7049, Appendix D, Figure 3:
10803 // As half-precision floating-point numbers were only added
10804 // to IEEE 754 in 2008, today's programming platforms often
10805 // still only have limited support for them. It is very
10806 // easy to include at least decoding support for them even
10807 // without such support. An example of a small decoder for
10808 // half-precision floating-point numbers in the C language
10809 // is shown in Fig. 3.
10810 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
10811 const double val = [&half]
10812 {
10813 const int exp = (half >> 10u) & 0x1Fu;
10814 const unsigned int mant = half & 0x3FFu;
10815 JSON_ASSERT(0 <= exp&& exp <= 32);
10816 JSON_ASSERT(mant <= 1024);
10817 switch (exp)
10818 {
10819 case 0:
10820 return std::ldexp(mant, -24);
10821 case 31:
10822 return (mant == 0)
10823 ? std::numeric_limits<double>::infinity()
10824 : std::numeric_limits<double>::quiet_NaN();
10825 default:
10826 return std::ldexp(mant + 1024, exp - 25);
10827 }
10828 }();
10829 return sax->number_float((half & 0x8000u) != 0
10830 ? static_cast<number_float_t>(-val)
10831 : static_cast<number_float_t>(val), "");
10832 }
10833
10834 case 'd':
10835 {
10836 float number{};
10837 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
10838 }
10839
10840 case 'D':
10841 {
10842 double number{};
10843 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
10844 }
10845
10846 case 'H':
10847 {
10848 return get_ubjson_high_precision_number();
10849 }
10850
10851 case 'C': // char
10852 {
10853 get();
10854 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
10855 {
10856 return false;
10857 }
10858 if (JSON_HEDLEY_UNLIKELY(current > 127))
10859 {
10860 auto last_token = get_token_string();
10861 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10862 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
10863 }
10864 string_t s(1, static_cast<typename string_t::value_type>(current));
10865 return sax->string(s);
10866 }
10867
10868 case 'S': // string
10869 {
10870 string_t s;
10871 return get_ubjson_string(s) && sax->string(s);
10872 }
10873
10874 case '[': // array
10875 return get_ubjson_array();
10876
10877 case '{': // object
10878 return get_ubjson_object();
10879
10880 default: // anything else
10881 break;
10882 }
10883 auto last_token = get_token_string();
10884 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
10885 }
10886
10890 bool get_ubjson_array()
10891 {
10892 std::pair<std::size_t, char_int_type> size_and_type;
10893 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10894 {
10895 return false;
10896 }
10897
10898 // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
10899 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
10900
10901 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
10902 {
10903 std::map<char_int_type, string_t> bjdtype = {{'U', "uint8"}, {'i', "int8"}, {'u', "uint16"}, {'I', "int16"},
10904 {'m', "uint32"}, {'l', "int32"}, {'M', "uint64"}, {'L', "int64"}, {'d', "single"}, {'D', "double"}, {'C', "char"}
10905 };
10906
10907 size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
10908
10909 string_t key = "_ArrayType_";
10910 if (JSON_HEDLEY_UNLIKELY(bjdtype.count(size_and_type.second) == 0))
10911 {
10912 auto last_token = get_token_string();
10913 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10914 exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
10915 }
10916
10917 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(bjdtype[size_and_type.second]) ))
10918 {
10919 return false;
10920 }
10921
10922 if (size_and_type.second == 'C')
10923 {
10924 size_and_type.second = 'U';
10925 }
10926
10927 key = "_ArrayData_";
10928 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
10929 {
10930 return false;
10931 }
10932
10933 for (std::size_t i = 0; i < size_and_type.first; ++i)
10934 {
10935 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10936 {
10937 return false;
10938 }
10939 }
10940
10941 return (sax->end_array() && sax->end_object());
10942 }
10943
10944 if (size_and_type.first != string_t::npos)
10945 {
10946 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10947 {
10948 return false;
10949 }
10950
10951 if (size_and_type.second != 0)
10952 {
10953 if (size_and_type.second != 'N')
10954 {
10955 for (std::size_t i = 0; i < size_and_type.first; ++i)
10956 {
10957 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10958 {
10959 return false;
10960 }
10961 }
10962 }
10963 }
10964 else
10965 {
10966 for (std::size_t i = 0; i < size_and_type.first; ++i)
10967 {
10968 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10969 {
10970 return false;
10971 }
10972 }
10973 }
10974 }
10975 else
10976 {
10977 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
10978 {
10979 return false;
10980 }
10981
10982 while (current != ']')
10983 {
10984 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10985 {
10986 return false;
10987 }
10988 get_ignore_noop();
10989 }
10990 }
10991
10992 return sax->end_array();
10993 }
10994
10998 bool get_ubjson_object()
10999 {
11000 std::pair<std::size_t, char_int_type> size_and_type;
11001 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11002 {
11003 return false;
11004 }
11005
11006 // do not accept ND-array size in objects in BJData
11007 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11008 {
11009 auto last_token = get_token_string();
11010 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11011 exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11012 }
11013
11014 string_t key;
11015 if (size_and_type.first != string_t::npos)
11016 {
11017 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11018 {
11019 return false;
11020 }
11021
11022 if (size_and_type.second != 0)
11023 {
11024 for (std::size_t i = 0; i < size_and_type.first; ++i)
11025 {
11026 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11027 {
11028 return false;
11029 }
11030 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11031 {
11032 return false;
11033 }
11034 key.clear();
11035 }
11036 }
11037 else
11038 {
11039 for (std::size_t i = 0; i < size_and_type.first; ++i)
11040 {
11041 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11042 {
11043 return false;
11044 }
11045 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11046 {
11047 return false;
11048 }
11049 key.clear();
11050 }
11051 }
11052 }
11053 else
11054 {
11055 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11056 {
11057 return false;
11058 }
11059
11060 while (current != '}')
11061 {
11062 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11063 {
11064 return false;
11065 }
11066 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11067 {
11068 return false;
11069 }
11070 get_ignore_noop();
11071 key.clear();
11072 }
11073 }
11074
11075 return sax->end_object();
11076 }
11077
11078 // Note, no reader for UBJSON binary types is implemented because they do
11079 // not exist
11080
11081 bool get_ubjson_high_precision_number()
11082 {
11083 // get size of following number string
11084 std::size_t size{};
11085 bool is_ndarray = false;
11086 auto res = get_ubjson_size_value(size, is_ndarray);
11087 if (JSON_HEDLEY_UNLIKELY(!res))
11088 {
11089 return res;
11090 }
11091
11092 // get number string
11093 std::vector<char> number_vector;
11094 for (std::size_t i = 0; i < size; ++i)
11095 {
11096 get();
11097 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11098 {
11099 return false;
11100 }
11101 number_vector.push_back(static_cast<char>(current));
11102 }
11103
11104 // parse number string
11105 using ia_type = decltype(detail::input_adapter(number_vector));
11106 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11107 const auto result_number = number_lexer.scan();
11108 const auto number_string = number_lexer.get_token_string();
11109 const auto result_remainder = number_lexer.scan();
11110
11111 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11112
11113 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11114 {
11115 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11116 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11117 }
11118
11119 switch (result_number)
11120 {
11121 case token_type::value_integer:
11122 return sax->number_integer(number_lexer.get_number_integer());
11123 case token_type::value_unsigned:
11124 return sax->number_unsigned(number_lexer.get_number_unsigned());
11125 case token_type::value_float:
11126 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11127 case token_type::uninitialized:
11128 case token_type::literal_true:
11129 case token_type::literal_false:
11130 case token_type::literal_null:
11131 case token_type::value_string:
11132 case token_type::begin_array:
11133 case token_type::begin_object:
11134 case token_type::end_array:
11135 case token_type::end_object:
11136 case token_type::name_separator:
11137 case token_type::value_separator:
11138 case token_type::parse_error:
11139 case token_type::end_of_input:
11140 case token_type::literal_or_value:
11141 default:
11142 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11143 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11144 }
11145 }
11146
11148 // Utility functions //
11150
11160 char_int_type get()
11161 {
11162 ++chars_read;
11163 return current = ia.get_character();
11164 }
11165
11169 char_int_type get_ignore_noop()
11170 {
11171 do
11172 {
11173 get();
11174 }
11175 while (current == 'N');
11176
11177 return current;
11178 }
11179
11180 /*
11181 @brief read a number from the input
11182
11183 @tparam NumberType the type of the number
11184 @param[in] format the current format (for diagnostics)
11185 @param[out] result number of type @a NumberType
11186
11187 @return whether conversion completed
11188
11189 @note This function needs to respect the system's endianness, because
11190 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11191 (big endian) and therefore need reordering on little endian systems.
11192 On the other hand, BSON and BJData use little endian and should reorder
11193 on big endian systems.
11194 */
11195 template<typename NumberType, bool InputIsLittleEndian = false>
11196 bool get_number(const input_format_t format, NumberType& result)
11197 {
11198 // step 1: read input into array with system's byte order
11199 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11200 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11201 {
11202 get();
11203 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11204 {
11205 return false;
11206 }
11207
11208 // reverse byte order prior to conversion if necessary
11209 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11210 {
11211 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11212 }
11213 else
11214 {
11215 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11216 }
11217 }
11218
11219 // step 2: convert array into number of type T and return
11220 std::memcpy(&result, vec.data(), sizeof(NumberType));
11221 return true;
11222 }
11223
11238 template<typename NumberType>
11239 bool get_string(const input_format_t format,
11240 const NumberType len,
11241 string_t& result)
11242 {
11243 bool success = true;
11244 for (NumberType i = 0; i < len; i++)
11245 {
11246 get();
11247 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11248 {
11249 success = false;
11250 break;
11251 }
11252 result.push_back(static_cast<typename string_t::value_type>(current));
11253 }
11254 return success;
11255 }
11256
11271 template<typename NumberType>
11272 bool get_binary(const input_format_t format,
11273 const NumberType len,
11274 binary_t& result)
11275 {
11276 bool success = true;
11277 for (NumberType i = 0; i < len; i++)
11278 {
11279 get();
11280 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11281 {
11282 success = false;
11283 break;
11284 }
11285 result.push_back(static_cast<std::uint8_t>(current));
11286 }
11287 return success;
11288 }
11289
11296 bool unexpect_eof(const input_format_t format, const char* context) const
11297 {
11298 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11299 {
11300 return sax->parse_error(chars_read, "<end of file>",
11301 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11302 }
11303 return true;
11304 }
11305
11309 std::string get_token_string() const
11310 {
11311 std::array<char, 3> cr{{}};
11312 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11313 return std::string{cr.data()};
11314 }
11315
11322 std::string exception_message(const input_format_t format,
11323 const std::string& detail,
11324 const std::string& context) const
11325 {
11326 std::string error_msg = "syntax error while parsing ";
11327
11328 switch (format)
11329 {
11331 error_msg += "CBOR";
11332 break;
11333
11335 error_msg += "MessagePack";
11336 break;
11337
11339 error_msg += "UBJSON";
11340 break;
11341
11343 error_msg += "BSON";
11344 break;
11345
11347 error_msg += "BJData";
11348 break;
11349
11350 case input_format_t::json: // LCOV_EXCL_LINE
11351 default: // LCOV_EXCL_LINE
11352 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
11353 }
11354
11355 return concat(error_msg, ' ', context, ": ", detail);
11356 }
11357
11358 private:
11360 InputAdapterType ia;
11361
11363 char_int_type current = std::char_traits<char_type>::eof();
11364
11366 std::size_t chars_read = 0;
11367
11369 const bool is_little_endian = little_endianness();
11370
11372 const input_format_t input_format = input_format_t::json;
11373
11375 json_sax_t* sax = nullptr;
11376};
11377} // namespace detail
11378} // namespace nlohmann
11379
11380// #include <nlohmann/detail/input/input_adapters.hpp>
11381
11382// #include <nlohmann/detail/input/lexer.hpp>
11383
11384// #include <nlohmann/detail/input/parser.hpp>
11385
11386
11387#include <cmath> // isfinite
11388#include <cstdint> // uint8_t
11389#include <functional> // function
11390#include <string> // string
11391#include <utility> // move
11392#include <vector> // vector
11393
11394// #include <nlohmann/detail/exceptions.hpp>
11395
11396// #include <nlohmann/detail/input/input_adapters.hpp>
11397
11398// #include <nlohmann/detail/input/json_sax.hpp>
11399
11400// #include <nlohmann/detail/input/lexer.hpp>
11401
11402// #include <nlohmann/detail/macro_scope.hpp>
11403
11404// #include <nlohmann/detail/meta/is_sax.hpp>
11405
11406// #include <nlohmann/detail/string_concat.hpp>
11407
11408// #include <nlohmann/detail/value_t.hpp>
11409
11410
11411namespace nlohmann
11412{
11413namespace detail
11414{
11416// parser //
11418
11419enum class parse_event_t : std::uint8_t
11420{
11424 object_end,
11428 array_end,
11430 key,
11432 value
11433};
11434
11435template<typename BasicJsonType>
11437 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
11438
11444template<typename BasicJsonType, typename InputAdapterType>
11446{
11447 using number_integer_t = typename BasicJsonType::number_integer_t;
11448 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
11449 using number_float_t = typename BasicJsonType::number_float_t;
11450 using string_t = typename BasicJsonType::string_t;
11452 using token_type = typename lexer_t::token_type;
11453
11454 public:
11456 explicit parser(InputAdapterType&& adapter,
11457 const parser_callback_t<BasicJsonType> cb = nullptr,
11458 const bool allow_exceptions_ = true,
11459 const bool skip_comments = false)
11460 : callback(cb)
11461 , m_lexer(std::move(adapter), skip_comments)
11462 , allow_exceptions(allow_exceptions_)
11463 {
11464 // read first token
11465 get_token();
11466 }
11467
11478 void parse(const bool strict, BasicJsonType& result)
11479 {
11480 if (callback)
11481 {
11482 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11483 sax_parse_internal(&sdp);
11484
11485 // in strict mode, input must be completely read
11486 if (strict && (get_token() != token_type::end_of_input))
11487 {
11488 sdp.parse_error(m_lexer.get_position(),
11489 m_lexer.get_token_string(),
11490 parse_error::create(101, m_lexer.get_position(),
11491 exception_message(token_type::end_of_input, "value"), nullptr));
11492 }
11493
11494 // in case of an error, return discarded value
11495 if (sdp.is_errored())
11496 {
11497 result = value_t::discarded;
11498 return;
11499 }
11500
11501 // set top-level value to null if it was discarded by the callback
11502 // function
11503 if (result.is_discarded())
11504 {
11505 result = nullptr;
11506 }
11507 }
11508 else
11509 {
11510 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11511 sax_parse_internal(&sdp);
11512
11513 // in strict mode, input must be completely read
11514 if (strict && (get_token() != token_type::end_of_input))
11515 {
11516 sdp.parse_error(m_lexer.get_position(),
11517 m_lexer.get_token_string(),
11518 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11519 }
11520
11521 // in case of an error, return discarded value
11522 if (sdp.is_errored())
11523 {
11524 result = value_t::discarded;
11525 return;
11526 }
11527 }
11528
11529 result.assert_invariant();
11530 }
11531
11538 bool accept(const bool strict = true)
11539 {
11541 return sax_parse(&sax_acceptor, strict);
11542 }
11543
11544 template<typename SAX>
11546 bool sax_parse(SAX* sax, const bool strict = true)
11547 {
11549 const bool result = sax_parse_internal(sax);
11550
11551 // strict mode: next byte must be EOF
11552 if (result && strict && (get_token() != token_type::end_of_input))
11553 {
11554 return sax->parse_error(m_lexer.get_position(),
11555 m_lexer.get_token_string(),
11556 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11557 }
11558
11559 return result;
11560 }
11561
11562 private:
11563 template<typename SAX>
11565 bool sax_parse_internal(SAX* sax)
11566 {
11567 // stack to remember the hierarchy of structured values we are parsing
11568 // true = array; false = object
11569 std::vector<bool> states;
11570 // value to avoid a goto (see comment where set to true)
11571 bool skip_to_state_evaluation = false;
11572
11573 while (true)
11574 {
11575 if (!skip_to_state_evaluation)
11576 {
11577 // invariant: get_token() was called before each iteration
11578 switch (last_token)
11579 {
11580 case token_type::begin_object:
11581 {
11582 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11583 {
11584 return false;
11585 }
11586
11587 // closing } -> we are done
11588 if (get_token() == token_type::end_object)
11589 {
11590 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11591 {
11592 return false;
11593 }
11594 break;
11595 }
11596
11597 // parse key
11598 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11599 {
11600 return sax->parse_error(m_lexer.get_position(),
11601 m_lexer.get_token_string(),
11602 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11603 }
11604 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11605 {
11606 return false;
11607 }
11608
11609 // parse separator (:)
11610 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11611 {
11612 return sax->parse_error(m_lexer.get_position(),
11613 m_lexer.get_token_string(),
11614 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11615 }
11616
11617 // remember we are now inside an object
11618 states.push_back(false);
11619
11620 // parse values
11621 get_token();
11622 continue;
11623 }
11624
11625 case token_type::begin_array:
11626 {
11627 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11628 {
11629 return false;
11630 }
11631
11632 // closing ] -> we are done
11633 if (get_token() == token_type::end_array)
11634 {
11635 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11636 {
11637 return false;
11638 }
11639 break;
11640 }
11641
11642 // remember we are now inside an array
11643 states.push_back(true);
11644
11645 // parse values (no need to call get_token)
11646 continue;
11647 }
11648
11649 case token_type::value_float:
11650 {
11651 const auto res = m_lexer.get_number_float();
11652
11653 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11654 {
11655 return sax->parse_error(m_lexer.get_position(),
11656 m_lexer.get_token_string(),
11657 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
11658 }
11659
11660 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11661 {
11662 return false;
11663 }
11664
11665 break;
11666 }
11667
11668 case token_type::literal_false:
11669 {
11670 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11671 {
11672 return false;
11673 }
11674 break;
11675 }
11676
11677 case token_type::literal_null:
11678 {
11679 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11680 {
11681 return false;
11682 }
11683 break;
11684 }
11685
11686 case token_type::literal_true:
11687 {
11688 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11689 {
11690 return false;
11691 }
11692 break;
11693 }
11694
11695 case token_type::value_integer:
11696 {
11697 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11698 {
11699 return false;
11700 }
11701 break;
11702 }
11703
11704 case token_type::value_string:
11705 {
11706 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11707 {
11708 return false;
11709 }
11710 break;
11711 }
11712
11713 case token_type::value_unsigned:
11714 {
11715 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11716 {
11717 return false;
11718 }
11719 break;
11720 }
11721
11722 case token_type::parse_error:
11723 {
11724 // using "uninitialized" to avoid "expected" message
11725 return sax->parse_error(m_lexer.get_position(),
11726 m_lexer.get_token_string(),
11727 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
11728 }
11729
11730 case token_type::uninitialized:
11731 case token_type::end_array:
11732 case token_type::end_object:
11733 case token_type::name_separator:
11734 case token_type::value_separator:
11735 case token_type::end_of_input:
11736 case token_type::literal_or_value:
11737 default: // the last token was unexpected
11738 {
11739 return sax->parse_error(m_lexer.get_position(),
11740 m_lexer.get_token_string(),
11741 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
11742 }
11743 }
11744 }
11745 else
11746 {
11747 skip_to_state_evaluation = false;
11748 }
11749
11750 // we reached this line after we successfully parsed a value
11751 if (states.empty())
11752 {
11753 // empty stack: we reached the end of the hierarchy: done
11754 return true;
11755 }
11756
11757 if (states.back()) // array
11758 {
11759 // comma -> next value
11760 if (get_token() == token_type::value_separator)
11761 {
11762 // parse a new value
11763 get_token();
11764 continue;
11765 }
11766
11767 // closing ]
11768 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11769 {
11770 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11771 {
11772 return false;
11773 }
11774
11775 // We are done with this array. Before we can parse a
11776 // new value, we need to evaluate the new state first.
11777 // By setting skip_to_state_evaluation to false, we
11778 // are effectively jumping to the beginning of this if.
11779 JSON_ASSERT(!states.empty());
11780 states.pop_back();
11781 skip_to_state_evaluation = true;
11782 continue;
11783 }
11784
11785 return sax->parse_error(m_lexer.get_position(),
11786 m_lexer.get_token_string(),
11787 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
11788 }
11789
11790 // states.back() is false -> object
11791
11792 // comma -> next value
11793 if (get_token() == token_type::value_separator)
11794 {
11795 // parse key
11796 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11797 {
11798 return sax->parse_error(m_lexer.get_position(),
11799 m_lexer.get_token_string(),
11800 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11801 }
11802
11803 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11804 {
11805 return false;
11806 }
11807
11808 // parse separator (:)
11809 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11810 {
11811 return sax->parse_error(m_lexer.get_position(),
11812 m_lexer.get_token_string(),
11813 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11814 }
11815
11816 // parse values
11817 get_token();
11818 continue;
11819 }
11820
11821 // closing }
11822 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11823 {
11824 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11825 {
11826 return false;
11827 }
11828
11829 // We are done with this object. Before we can parse a
11830 // new value, we need to evaluate the new state first.
11831 // By setting skip_to_state_evaluation to false, we
11832 // are effectively jumping to the beginning of this if.
11833 JSON_ASSERT(!states.empty());
11834 states.pop_back();
11835 skip_to_state_evaluation = true;
11836 continue;
11837 }
11838
11839 return sax->parse_error(m_lexer.get_position(),
11840 m_lexer.get_token_string(),
11841 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
11842 }
11843 }
11844
11846 token_type get_token()
11847 {
11848 return last_token = m_lexer.scan();
11849 }
11850
11851 std::string exception_message(const token_type expected, const std::string& context)
11852 {
11853 std::string error_msg = "syntax error ";
11854
11855 if (!context.empty())
11856 {
11857 error_msg += concat("while parsing ", context, ' ');
11858 }
11859
11860 error_msg += "- ";
11861
11862 if (last_token == token_type::parse_error)
11863 {
11864 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
11865 m_lexer.get_token_string(), '\'');
11866 }
11867 else
11868 {
11869 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
11870 }
11871
11872 if (expected != token_type::uninitialized)
11873 {
11874 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
11875 }
11876
11877 return error_msg;
11878 }
11879
11880 private:
11882 const parser_callback_t<BasicJsonType> callback = nullptr;
11884 token_type last_token = token_type::uninitialized;
11886 lexer_t m_lexer;
11888 const bool allow_exceptions = true;
11889};
11890
11891} // namespace detail
11892} // namespace nlohmann
11893
11894// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11895
11896
11897// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11898
11899
11900#include <cstddef> // ptrdiff_t
11901#include <limits> // numeric_limits
11902
11903// #include <nlohmann/detail/macro_scope.hpp>
11904
11905
11906namespace nlohmann
11907{
11908namespace detail
11909{
11910/*
11911@brief an iterator for primitive JSON types
11912
11913This class models an iterator for primitive JSON types (boolean, number,
11914string). It's only purpose is to allow the iterator/const_iterator classes
11915to "iterate" over primitive values. Internally, the iterator is modeled by
11916a `difference_type` variable. Value begin_value (`0`) models the begin,
11917end_value (`1`) models past the end.
11918*/
11920{
11921 private:
11922 using difference_type = std::ptrdiff_t;
11923 static constexpr difference_type begin_value = 0;
11924 static constexpr difference_type end_value = begin_value + 1;
11925
11928 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11929
11930 public:
11931 constexpr difference_type get_value() const noexcept
11932 {
11933 return m_it;
11934 }
11935
11937 void set_begin() noexcept
11938 {
11939 m_it = begin_value;
11940 }
11941
11943 void set_end() noexcept
11944 {
11945 m_it = end_value;
11946 }
11947
11949 constexpr bool is_begin() const noexcept
11950 {
11951 return m_it == begin_value;
11952 }
11953
11955 constexpr bool is_end() const noexcept
11956 {
11957 return m_it == end_value;
11958 }
11959
11960 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11961 {
11962 return lhs.m_it == rhs.m_it;
11963 }
11964
11965 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11966 {
11967 return lhs.m_it < rhs.m_it;
11968 }
11969
11970 primitive_iterator_t operator+(difference_type n) noexcept
11971 {
11972 auto result = *this;
11973 result += n;
11974 return result;
11975 }
11976
11977 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11978 {
11979 return lhs.m_it - rhs.m_it;
11980 }
11981
11983 {
11984 ++m_it;
11985 return *this;
11986 }
11987
11988 primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
11989 {
11990 auto result = *this;
11991 ++m_it;
11992 return result;
11993 }
11994
11996 {
11997 --m_it;
11998 return *this;
11999 }
12000
12001 primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12002 {
12003 auto result = *this;
12004 --m_it;
12005 return result;
12006 }
12007
12008 primitive_iterator_t& operator+=(difference_type n) noexcept
12009 {
12010 m_it += n;
12011 return *this;
12012 }
12013
12014 primitive_iterator_t& operator-=(difference_type n) noexcept
12015 {
12016 m_it -= n;
12017 return *this;
12018 }
12019};
12020} // namespace detail
12021} // namespace nlohmann
12022
12023
12024namespace nlohmann
12025{
12026namespace detail
12027{
12034template<typename BasicJsonType> struct internal_iterator
12035{
12037 typename BasicJsonType::object_t::iterator object_iterator {};
12039 typename BasicJsonType::array_t::iterator array_iterator {};
12042};
12043} // namespace detail
12044} // namespace nlohmann
12045
12046// #include <nlohmann/detail/iterators/iter_impl.hpp>
12047
12048
12049#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12050#include <type_traits> // conditional, is_const, remove_const
12051
12052// #include <nlohmann/detail/exceptions.hpp>
12053
12054// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12055
12056// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12057
12058// #include <nlohmann/detail/macro_scope.hpp>
12059
12060// #include <nlohmann/detail/meta/cpp_future.hpp>
12061
12062// #include <nlohmann/detail/meta/type_traits.hpp>
12063
12064// #include <nlohmann/detail/value_t.hpp>
12065
12066
12067namespace nlohmann
12068{
12069namespace detail
12070{
12071// forward declare, to be able to friend it later on
12072template<typename IteratorType> class iteration_proxy;
12073template<typename IteratorType> class iteration_proxy_value;
12074
12091template<typename BasicJsonType>
12092class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12093{
12095 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12097 friend other_iter_impl;
12098 friend BasicJsonType;
12101
12102 using object_t = typename BasicJsonType::object_t;
12103 using array_t = typename BasicJsonType::array_t;
12104 // make sure BasicJsonType is basic_json or const basic_json
12106 "iter_impl only accepts (const) basic_json");
12107
12108 public:
12109
12115 using iterator_category = std::bidirectional_iterator_tag;
12116
12118 using value_type = typename BasicJsonType::value_type;
12120 using difference_type = typename BasicJsonType::difference_type;
12122 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12123 typename BasicJsonType::const_pointer,
12124 typename BasicJsonType::pointer>::type;
12127 typename std::conditional<std::is_const<BasicJsonType>::value,
12128 typename BasicJsonType::const_reference,
12129 typename BasicJsonType::reference>::type;
12130
12131 iter_impl() = default;
12132 ~iter_impl() = default;
12133 iter_impl(iter_impl&&) noexcept = default;
12134 iter_impl& operator=(iter_impl&&) noexcept = default;
12135
12142 explicit iter_impl(pointer object) noexcept : m_object(object)
12143 {
12144 JSON_ASSERT(m_object != nullptr);
12145
12146 switch (m_object->m_type)
12147 {
12148 case value_t::object:
12149 {
12150 m_it.object_iterator = typename object_t::iterator();
12151 break;
12152 }
12153
12154 case value_t::array:
12155 {
12156 m_it.array_iterator = typename array_t::iterator();
12157 break;
12158 }
12159
12160 case value_t::null:
12161 case value_t::string:
12162 case value_t::boolean:
12166 case value_t::binary:
12167 case value_t::discarded:
12168 default:
12169 {
12171 break;
12172 }
12173 }
12174 }
12175
12193 : m_object(other.m_object), m_it(other.m_it)
12194 {}
12195
12203 {
12204 if (&other != this)
12205 {
12206 m_object = other.m_object;
12207 m_it = other.m_it;
12208 }
12209 return *this;
12210 }
12211
12217 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12218 : m_object(other.m_object), m_it(other.m_it)
12219 {}
12220
12227 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12228 {
12229 m_object = other.m_object;
12230 m_it = other.m_it;
12231 return *this;
12232 }
12233
12239 void set_begin() noexcept
12240 {
12241 JSON_ASSERT(m_object != nullptr);
12242
12243 switch (m_object->m_type)
12244 {
12245 case value_t::object:
12246 {
12247 m_it.object_iterator = m_object->m_value.object->begin();
12248 break;
12249 }
12250
12251 case value_t::array:
12252 {
12253 m_it.array_iterator = m_object->m_value.array->begin();
12254 break;
12255 }
12256
12257 case value_t::null:
12258 {
12259 // set to end so begin()==end() is true: null is empty
12261 break;
12262 }
12263
12264 case value_t::string:
12265 case value_t::boolean:
12269 case value_t::binary:
12270 case value_t::discarded:
12271 default:
12272 {
12274 break;
12275 }
12276 }
12277 }
12278
12283 void set_end() noexcept
12284 {
12285 JSON_ASSERT(m_object != nullptr);
12286
12287 switch (m_object->m_type)
12288 {
12289 case value_t::object:
12290 {
12291 m_it.object_iterator = m_object->m_value.object->end();
12292 break;
12293 }
12294
12295 case value_t::array:
12296 {
12297 m_it.array_iterator = m_object->m_value.array->end();
12298 break;
12299 }
12300
12301 case value_t::null:
12302 case value_t::string:
12303 case value_t::boolean:
12307 case value_t::binary:
12308 case value_t::discarded:
12309 default:
12310 {
12312 break;
12313 }
12314 }
12315 }
12316
12317 public:
12323 {
12324 JSON_ASSERT(m_object != nullptr);
12325
12326 switch (m_object->m_type)
12327 {
12328 case value_t::object:
12329 {
12330 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12331 return m_it.object_iterator->second;
12332 }
12333
12334 case value_t::array:
12335 {
12336 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12337 return *m_it.array_iterator;
12338 }
12339
12340 case value_t::null:
12341 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12342
12343 case value_t::string:
12344 case value_t::boolean:
12348 case value_t::binary:
12349 case value_t::discarded:
12350 default:
12351 {
12353 {
12354 return *m_object;
12355 }
12356
12357 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12358 }
12359 }
12360 }
12361
12367 {
12368 JSON_ASSERT(m_object != nullptr);
12369
12370 switch (m_object->m_type)
12371 {
12372 case value_t::object:
12373 {
12374 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12375 return &(m_it.object_iterator->second);
12376 }
12377
12378 case value_t::array:
12379 {
12380 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12381 return &*m_it.array_iterator;
12382 }
12383
12384 case value_t::null:
12385 case value_t::string:
12386 case value_t::boolean:
12390 case value_t::binary:
12391 case value_t::discarded:
12392 default:
12393 {
12395 {
12396 return m_object;
12397 }
12398
12399 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12400 }
12401 }
12402 }
12403
12408 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
12409 {
12410 auto result = *this;
12411 ++(*this);
12412 return result;
12413 }
12414
12420 {
12421 JSON_ASSERT(m_object != nullptr);
12422
12423 switch (m_object->m_type)
12424 {
12425 case value_t::object:
12426 {
12427 std::advance(m_it.object_iterator, 1);
12428 break;
12429 }
12430
12431 case value_t::array:
12432 {
12433 std::advance(m_it.array_iterator, 1);
12434 break;
12435 }
12436
12437 case value_t::null:
12438 case value_t::string:
12439 case value_t::boolean:
12443 case value_t::binary:
12444 case value_t::discarded:
12445 default:
12446 {
12448 break;
12449 }
12450 }
12451
12452 return *this;
12453 }
12454
12459 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
12460 {
12461 auto result = *this;
12462 --(*this);
12463 return result;
12464 }
12465
12471 {
12472 JSON_ASSERT(m_object != nullptr);
12473
12474 switch (m_object->m_type)
12475 {
12476 case value_t::object:
12477 {
12478 std::advance(m_it.object_iterator, -1);
12479 break;
12480 }
12481
12482 case value_t::array:
12483 {
12484 std::advance(m_it.array_iterator, -1);
12485 break;
12486 }
12487
12488 case value_t::null:
12489 case value_t::string:
12490 case value_t::boolean:
12494 case value_t::binary:
12495 case value_t::discarded:
12496 default:
12497 {
12499 break;
12500 }
12501 }
12502
12503 return *this;
12504 }
12505
12510 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12511 bool operator==(const IterImpl& other) const
12512 {
12513 // if objects are not the same, the comparison is undefined
12514 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12515 {
12516 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12517 }
12518
12519 JSON_ASSERT(m_object != nullptr);
12520
12521 switch (m_object->m_type)
12522 {
12523 case value_t::object:
12524 return (m_it.object_iterator == other.m_it.object_iterator);
12525
12526 case value_t::array:
12527 return (m_it.array_iterator == other.m_it.array_iterator);
12528
12529 case value_t::null:
12530 case value_t::string:
12531 case value_t::boolean:
12535 case value_t::binary:
12536 case value_t::discarded:
12537 default:
12538 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12539 }
12540 }
12541
12546 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12547 bool operator!=(const IterImpl& other) const
12548 {
12549 return !operator==(other);
12550 }
12551
12556 bool operator<(const iter_impl& other) const
12557 {
12558 // if objects are not the same, the comparison is undefined
12559 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12560 {
12561 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12562 }
12563
12564 JSON_ASSERT(m_object != nullptr);
12565
12566 switch (m_object->m_type)
12567 {
12568 case value_t::object:
12569 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
12570
12571 case value_t::array:
12572 return (m_it.array_iterator < other.m_it.array_iterator);
12573
12574 case value_t::null:
12575 case value_t::string:
12576 case value_t::boolean:
12580 case value_t::binary:
12581 case value_t::discarded:
12582 default:
12584 }
12585 }
12586
12591 bool operator<=(const iter_impl& other) const
12592 {
12593 return !other.operator < (*this);
12594 }
12595
12600 bool operator>(const iter_impl& other) const
12601 {
12602 return !operator<=(other);
12603 }
12604
12609 bool operator>=(const iter_impl& other) const
12610 {
12611 return !operator<(other);
12612 }
12613
12619 {
12620 JSON_ASSERT(m_object != nullptr);
12621
12622 switch (m_object->m_type)
12623 {
12624 case value_t::object:
12625 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12626
12627 case value_t::array:
12628 {
12629 std::advance(m_it.array_iterator, i);
12630 break;
12631 }
12632
12633 case value_t::null:
12634 case value_t::string:
12635 case value_t::boolean:
12639 case value_t::binary:
12640 case value_t::discarded:
12641 default:
12642 {
12644 break;
12645 }
12646 }
12647
12648 return *this;
12649 }
12650
12656 {
12657 return operator+=(-i);
12658 }
12659
12665 {
12666 auto result = *this;
12667 result += i;
12668 return result;
12669 }
12670
12676 {
12677 auto result = it;
12678 result += i;
12679 return result;
12680 }
12681
12687 {
12688 auto result = *this;
12689 result -= i;
12690 return result;
12691 }
12692
12698 {
12699 JSON_ASSERT(m_object != nullptr);
12700
12701 switch (m_object->m_type)
12702 {
12703 case value_t::object:
12704 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12705
12706 case value_t::array:
12707 return m_it.array_iterator - other.m_it.array_iterator;
12708
12709 case value_t::null:
12710 case value_t::string:
12711 case value_t::boolean:
12715 case value_t::binary:
12716 case value_t::discarded:
12717 default:
12719 }
12720 }
12721
12727 {
12728 JSON_ASSERT(m_object != nullptr);
12729
12730 switch (m_object->m_type)
12731 {
12732 case value_t::object:
12733 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
12734
12735 case value_t::array:
12736 return *std::next(m_it.array_iterator, n);
12737
12738 case value_t::null:
12739 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12740
12741 case value_t::string:
12742 case value_t::boolean:
12746 case value_t::binary:
12747 case value_t::discarded:
12748 default:
12749 {
12751 {
12752 return *m_object;
12753 }
12754
12755 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12756 }
12757 }
12758 }
12759
12764 const typename object_t::key_type& key() const
12765 {
12766 JSON_ASSERT(m_object != nullptr);
12767
12768 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12769 {
12770 return m_it.object_iterator->first;
12771 }
12772
12773 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
12774 }
12775
12781 {
12782 return operator*();
12783 }
12784
12787 pointer m_object = nullptr;
12790};
12791} // namespace detail
12792} // namespace nlohmann
12793
12794// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12795
12796// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12797
12798
12799#include <cstddef> // ptrdiff_t
12800#include <iterator> // reverse_iterator
12801#include <utility> // declval
12802
12803namespace nlohmann
12804{
12805namespace detail
12806{
12808// reverse_iterator //
12810
12829template<typename Base>
12830class json_reverse_iterator : public std::reverse_iterator<Base>
12831{
12832 public:
12833 using difference_type = std::ptrdiff_t;
12835 using base_iterator = std::reverse_iterator<Base>;
12837 using reference = typename Base::reference;
12838
12840 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12841 : base_iterator(it) {}
12842
12844 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12845
12847 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
12848 {
12849 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12850 }
12851
12854 {
12855 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12856 }
12857
12859 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
12860 {
12861 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12862 }
12863
12866 {
12867 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12868 }
12869
12872 {
12873 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12874 }
12875
12878 {
12879 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12880 }
12881
12884 {
12885 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12886 }
12887
12890 {
12891 return base_iterator(*this) - base_iterator(other);
12892 }
12893
12896 {
12897 return *(this->operator+(n));
12898 }
12899
12901 auto key() const -> decltype(std::declval<Base>().key())
12902 {
12903 auto it = --this->base();
12904 return it.key();
12905 }
12906
12909 {
12910 auto it = --this->base();
12911 return it.operator * ();
12912 }
12913};
12914} // namespace detail
12915} // namespace nlohmann
12916
12917// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12918
12919// #include <nlohmann/detail/json_pointer.hpp>
12920
12921
12922#include <algorithm> // all_of
12923#include <cctype> // isdigit
12924#include <cerrno> // errno, ERANGE
12925#include <cstdlib> // strtoull
12926#include <limits> // max
12927#include <numeric> // accumulate
12928#include <string> // string
12929#include <utility> // move
12930#include <vector> // vector
12931
12932// #include <nlohmann/detail/exceptions.hpp>
12933
12934// #include <nlohmann/detail/macro_scope.hpp>
12935
12936// #include <nlohmann/detail/string_concat.hpp>
12937
12938// #include <nlohmann/detail/string_escape.hpp>
12939
12940// #include <nlohmann/detail/value_t.hpp>
12941
12942
12943namespace nlohmann
12944{
12945
12948template<typename RefStringType>
12950{
12951 // allow basic_json to access private members
12953 friend class basic_json;
12954
12955 template<typename>
12956 friend class json_pointer;
12957
12958 template<typename T>
12959 struct string_t_helper
12960 {
12961 using type = T;
12962 };
12963
12965 struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
12966 {
12967 using type = StringType;
12968 };
12969
12970 public:
12971 // for backwards compatibility accept BasicJsonType
12972 using string_t = typename string_t_helper<RefStringType>::type;
12973
12976 explicit json_pointer(const string_t& s = "")
12977 : reference_tokens(split(s))
12978 {}
12979
12983 {
12984 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12985 string_t{},
12986 [](const string_t& a, const string_t& b)
12987 {
12988 return detail::concat(a, '/', detail::escape(b));
12989 });
12990 }
12991
12994 operator string_t() const
12995 {
12996 return to_string();
12997 }
12998
13002 {
13003 reference_tokens.insert(reference_tokens.end(),
13004 ptr.reference_tokens.begin(),
13005 ptr.reference_tokens.end());
13006 return *this;
13007 }
13008
13012 {
13013 push_back(std::move(token));
13014 return *this;
13015 }
13016
13019 json_pointer& operator/=(std::size_t array_idx)
13020 {
13021 return *this /= std::to_string(array_idx);
13022 }
13023
13027 const json_pointer& rhs)
13028 {
13029 return json_pointer(lhs) /= rhs;
13030 }
13031
13034 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13035 {
13036 return json_pointer(lhs) /= std::move(token);
13037 }
13038
13041 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13042 {
13043 return json_pointer(lhs) /= array_idx;
13044 }
13045
13049 {
13050 if (empty())
13051 {
13052 return *this;
13053 }
13054
13055 json_pointer res = *this;
13056 res.pop_back();
13057 return res;
13058 }
13059
13063 {
13065 {
13066 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13067 }
13068
13069 reference_tokens.pop_back();
13070 }
13071
13074 const string_t& back() const
13075 {
13077 {
13078 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13079 }
13080
13081 return reference_tokens.back();
13082 }
13083
13086 void push_back(const string_t& token)
13087 {
13088 reference_tokens.push_back(token);
13089 }
13090
13093 void push_back(string_t&& token)
13094 {
13095 reference_tokens.push_back(std::move(token));
13096 }
13097
13100 bool empty() const noexcept
13101 {
13102 return reference_tokens.empty();
13103 }
13104
13105 private:
13116 template<typename BasicJsonType>
13117 static typename BasicJsonType::size_type array_index(const string_t& s)
13118 {
13119 using size_type = typename BasicJsonType::size_type;
13120
13121 // error condition (cf. RFC 6901, Sect. 4)
13122 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13123 {
13124 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13125 }
13126
13127 // error condition (cf. RFC 6901, Sect. 4)
13128 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13129 {
13130 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13131 }
13132
13133 const char* p = s.c_str();
13134 char* p_end = nullptr;
13135 errno = 0; // strtoull doesn't reset errno
13136 unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13137 if (p == p_end // invalid input or empty string
13138 || errno == ERANGE // out of range
13139 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13140 {
13141 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13142 }
13143
13144 // only triggered on special platforms (like 32bit), see also
13145 // https://github.com/nlohmann/json/pull/2203
13146 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13147 {
13148 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13149 }
13150
13151 return static_cast<size_type>(res);
13152 }
13153
13155 json_pointer top() const
13156 {
13158 {
13159 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13160 }
13161
13162 json_pointer result = *this;
13163 result.reference_tokens = {reference_tokens[0]};
13164 return result;
13165 }
13166
13167 private:
13176 template<typename BasicJsonType>
13177 BasicJsonType& get_and_create(BasicJsonType& j) const
13178 {
13179 auto* result = &j;
13180
13181 // in case no reference tokens exist, return a reference to the JSON value
13182 // j which will be overwritten by a primitive value
13183 for (const auto& reference_token : reference_tokens)
13184 {
13185 switch (result->type())
13186 {
13188 {
13189 if (reference_token == "0")
13190 {
13191 // start a new array if reference token is 0
13192 result = &result->operator[](0);
13193 }
13194 else
13195 {
13196 // start a new object otherwise
13197 result = &result->operator[](reference_token);
13198 }
13199 break;
13200 }
13201
13203 {
13204 // create an entry in the object
13205 result = &result->operator[](reference_token);
13206 break;
13207 }
13208
13210 {
13211 // create an entry in the array
13212 result = &result->operator[](array_index<BasicJsonType>(reference_token));
13213 break;
13214 }
13215
13216 /*
13217 The following code is only reached if there exists a reference
13218 token _and_ the current value is primitive. In this case, we have
13219 an error situation, because primitive values may only occur as
13220 single value; that is, with an empty list of reference tokens.
13221 */
13229 default:
13230 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
13231 }
13232 }
13233
13234 return *result;
13235 }
13236
13256 template<typename BasicJsonType>
13257 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
13258 {
13259 for (const auto& reference_token : reference_tokens)
13260 {
13261 // convert null values to arrays or objects before continuing
13262 if (ptr->is_null())
13263 {
13264 // check if reference token is a number
13265 const bool nums =
13266 std::all_of(reference_token.begin(), reference_token.end(),
13267 [](const unsigned char x)
13268 {
13269 return std::isdigit(x);
13270 });
13271
13272 // change value to array for numbers or "-" or to object otherwise
13273 *ptr = (nums || reference_token == "-")
13276 }
13277
13278 switch (ptr->type())
13279 {
13281 {
13282 // use unchecked object access
13283 ptr = &ptr->operator[](reference_token);
13284 break;
13285 }
13286
13288 {
13289 if (reference_token == "-")
13290 {
13291 // explicitly treat "-" as index beyond the end
13292 ptr = &ptr->operator[](ptr->m_value.array->size());
13293 }
13294 else
13295 {
13296 // convert array index to number; unchecked access
13297 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13298 }
13299 break;
13300 }
13301
13310 default:
13311 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13312 }
13313 }
13314
13315 return *ptr;
13316 }
13317
13324 template<typename BasicJsonType>
13325 BasicJsonType& get_checked(BasicJsonType* ptr) const
13326 {
13327 for (const auto& reference_token : reference_tokens)
13328 {
13329 switch (ptr->type())
13330 {
13332 {
13333 // note: at performs range check
13334 ptr = &ptr->at(reference_token);
13335 break;
13336 }
13337
13339 {
13340 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13341 {
13342 // "-" always fails the range check
13344 "array index '-' (", std::to_string(ptr->m_value.array->size()),
13345 ") is out of range"), ptr));
13346 }
13347
13348 // note: at performs range check
13349 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13350 break;
13351 }
13352
13361 default:
13362 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13363 }
13364 }
13365
13366 return *ptr;
13367 }
13368
13382 template<typename BasicJsonType>
13383 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13384 {
13385 for (const auto& reference_token : reference_tokens)
13386 {
13387 switch (ptr->type())
13388 {
13390 {
13391 // use unchecked object access
13392 ptr = &ptr->operator[](reference_token);
13393 break;
13394 }
13395
13397 {
13398 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13399 {
13400 // "-" cannot be used for const access
13401 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
13402 }
13403
13404 // use unchecked array access
13405 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13406 break;
13407 }
13408
13417 default:
13418 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13419 }
13420 }
13421
13422 return *ptr;
13423 }
13424
13431 template<typename BasicJsonType>
13432 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13433 {
13434 for (const auto& reference_token : reference_tokens)
13435 {
13436 switch (ptr->type())
13437 {
13439 {
13440 // note: at performs range check
13441 ptr = &ptr->at(reference_token);
13442 break;
13443 }
13444
13446 {
13447 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13448 {
13449 // "-" always fails the range check
13451 "array index '-' (", std::to_string(ptr->m_value.array->size()),
13452 ") is out of range"), ptr));
13453 }
13454
13455 // note: at performs range check
13456 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13457 break;
13458 }
13459
13468 default:
13469 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13470 }
13471 }
13472
13473 return *ptr;
13474 }
13475
13480 template<typename BasicJsonType>
13481 bool contains(const BasicJsonType* ptr) const
13482 {
13483 for (const auto& reference_token : reference_tokens)
13484 {
13485 switch (ptr->type())
13486 {
13488 {
13489 if (!ptr->contains(reference_token))
13490 {
13491 // we did not find the key in the object
13492 return false;
13493 }
13494
13495 ptr = &ptr->operator[](reference_token);
13496 break;
13497 }
13498
13500 {
13501 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13502 {
13503 // "-" always fails the range check
13504 return false;
13505 }
13506 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13507 {
13508 // invalid char
13509 return false;
13510 }
13511 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13512 {
13513 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13514 {
13515 // first char should be between '1' and '9'
13516 return false;
13517 }
13518 for (std::size_t i = 1; i < reference_token.size(); i++)
13519 {
13520 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13521 {
13522 // other char should be between '0' and '9'
13523 return false;
13524 }
13525 }
13526 }
13527
13528 const auto idx = array_index<BasicJsonType>(reference_token);
13529 if (idx >= ptr->size())
13530 {
13531 // index out of range
13532 return false;
13533 }
13534
13535 ptr = &ptr->operator[](idx);
13536 break;
13537 }
13538
13547 default:
13548 {
13549 // we do not expect primitive values if there is still a
13550 // reference token to process
13551 return false;
13552 }
13553 }
13554 }
13555
13556 // no reference token left means we found a primitive value
13557 return true;
13558 }
13559
13569 static std::vector<string_t> split(const string_t& reference_string)
13570 {
13571 std::vector<string_t> result;
13572
13573 // special case: empty reference string -> no reference tokens
13574 if (reference_string.empty())
13575 {
13576 return result;
13577 }
13578
13579 // check if nonempty reference string begins with slash
13580 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13581 {
13582 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
13583 }
13584
13585 // extract the reference tokens:
13586 // - slash: position of the last read slash (or end of string)
13587 // - start: position after the previous slash
13588 for (
13589 // search for the first slash after the first character
13590 std::size_t slash = reference_string.find_first_of('/', 1),
13591 // set the beginning of the first reference token
13592 start = 1;
13593 // we can stop if start == 0 (if slash == string_t::npos)
13594 start != 0;
13595 // set the beginning of the next reference token
13596 // (will eventually be 0 if slash == string_t::npos)
13597 start = (slash == string_t::npos) ? 0 : slash + 1,
13598 // find next slash
13599 slash = reference_string.find_first_of('/', start))
13600 {
13601 // use the text between the beginning of the reference token
13602 // (start) and the last slash (slash).
13603 auto reference_token = reference_string.substr(start, slash - start);
13604
13605 // check reference tokens are properly escaped
13606 for (std::size_t pos = reference_token.find_first_of('~');
13607 pos != string_t::npos;
13608 pos = reference_token.find_first_of('~', pos + 1))
13609 {
13610 JSON_ASSERT(reference_token[pos] == '~');
13611
13612 // ~ must be followed by 0 or 1
13613 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13614 (reference_token[pos + 1] != '0' &&
13615 reference_token[pos + 1] != '1')))
13616 {
13617 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
13618 }
13619 }
13620
13621 // finally, store the reference token
13622 detail::unescape(reference_token);
13623 result.push_back(reference_token);
13624 }
13625
13626 return result;
13627 }
13628
13629 private:
13637 template<typename BasicJsonType>
13638 static void flatten(const string_t& reference_string,
13639 const BasicJsonType& value,
13640 BasicJsonType& result)
13641 {
13642 switch (value.type())
13643 {
13645 {
13646 if (value.m_value.array->empty())
13647 {
13648 // flatten empty array as null
13649 result[reference_string] = nullptr;
13650 }
13651 else
13652 {
13653 // iterate array and use index as reference string
13654 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13655 {
13656 flatten(detail::concat(reference_string, '/', std::to_string(i)),
13657 value.m_value.array->operator[](i), result);
13658 }
13659 }
13660 break;
13661 }
13662
13664 {
13665 if (value.m_value.object->empty())
13666 {
13667 // flatten empty object as null
13668 result[reference_string] = nullptr;
13669 }
13670 else
13671 {
13672 // iterate object and use keys as reference string
13673 for (const auto& element : *value.m_value.object)
13674 {
13675 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
13676 }
13677 }
13678 break;
13679 }
13680
13689 default:
13690 {
13691 // add primitive value with its reference string
13692 result[reference_string] = value;
13693 break;
13694 }
13695 }
13696 }
13697
13708 template<typename BasicJsonType>
13709 static BasicJsonType
13710 unflatten(const BasicJsonType& value)
13711 {
13712 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13713 {
13714 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
13715 }
13716
13717 BasicJsonType result;
13718
13719 // iterate the JSON object values
13720 for (const auto& element : *value.m_value.object)
13721 {
13722 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13723 {
13724 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
13725 }
13726
13727 // assign value to reference pointed to by JSON pointer; Note that if
13728 // the JSON pointer is "" (i.e., points to the whole value), function
13729 // get_and_create returns a reference to result itself. An assignment
13730 // will then create a primitive value.
13731 json_pointer(element.first).get_and_create(result) = element.second;
13732 }
13733
13734 return result;
13735 }
13736
13737 // can't use conversion operator because of ambiguity
13738 json_pointer<string_t> convert() const&
13739 {
13740 json_pointer<string_t> result;
13741 result.reference_tokens = reference_tokens;
13742 return result;
13743 }
13744
13745 json_pointer<string_t> convert()&&
13746 {
13747 json_pointer<string_t> result;
13748 result.reference_tokens = std::move(reference_tokens);
13749 return result;
13750 }
13751
13763 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13764 // NOLINTNEXTLINE(readability-redundant-declaration)
13765 friend bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
13766 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
13767
13779 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13780 // NOLINTNEXTLINE(readability-redundant-declaration)
13781 friend bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
13782 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
13783
13785 std::vector<string_t> reference_tokens;
13786};
13787
13788// functions cannot be defined inside class due to ODR violations
13789template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13791 json_pointer<RefStringTypeRhs> const& rhs) noexcept
13792{
13793 return lhs.reference_tokens == rhs.reference_tokens;
13794}
13795
13796template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13798 json_pointer<RefStringTypeRhs> const& rhs) noexcept
13799{
13800 return !(lhs == rhs);
13801}
13802} // namespace nlohmann
13803
13804// #include <nlohmann/detail/json_ref.hpp>
13805
13806
13807#include <initializer_list>
13808#include <utility>
13809
13810// #include <nlohmann/detail/meta/type_traits.hpp>
13811
13812
13813namespace nlohmann
13814{
13815namespace detail
13816{
13817template<typename BasicJsonType>
13819{
13820 public:
13821 using value_type = BasicJsonType;
13822
13824 : owned_value(std::move(value))
13825 {}
13826
13827 json_ref(const value_type& value)
13828 : value_ref(&value)
13829 {}
13830
13831 json_ref(std::initializer_list<json_ref> init)
13832 : owned_value(init)
13833 {}
13834
13835 template <
13836 class... Args,
13837 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13838 json_ref(Args && ... args)
13839 : owned_value(std::forward<Args>(args)...)
13840 {}
13841
13842 // class should be movable only
13843 json_ref(json_ref&&) noexcept = default;
13844 json_ref(const json_ref&) = delete;
13845 json_ref& operator=(const json_ref&) = delete;
13846 json_ref& operator=(json_ref&&) = delete;
13847 ~json_ref() = default;
13848
13850 {
13851 if (value_ref == nullptr)
13852 {
13853 return std::move(owned_value);
13854 }
13855 return *value_ref;
13856 }
13857
13858 value_type const& operator*() const
13859 {
13860 return value_ref ? *value_ref : owned_value;
13861 }
13862
13863 value_type const* operator->() const
13864 {
13865 return &** this;
13866 }
13867
13868 private:
13869 mutable value_type owned_value = nullptr;
13870 value_type const* value_ref = nullptr;
13871};
13872} // namespace detail
13873} // namespace nlohmann
13874
13875// #include <nlohmann/detail/macro_scope.hpp>
13876
13877// #include <nlohmann/detail/string_concat.hpp>
13878
13879// #include <nlohmann/detail/string_escape.hpp>
13880
13881// #include <nlohmann/detail/meta/cpp_future.hpp>
13882
13883// #include <nlohmann/detail/meta/type_traits.hpp>
13884
13885// #include <nlohmann/detail/output/binary_writer.hpp>
13886
13887
13888#include <algorithm> // reverse
13889#include <array> // array
13890#include <map> // map
13891#include <cmath> // isnan, isinf
13892#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13893#include <cstring> // memcpy
13894#include <limits> // numeric_limits
13895#include <string> // string
13896#include <utility> // move
13897#include <vector> // vector
13898
13899// #include <nlohmann/detail/input/binary_reader.hpp>
13900
13901// #include <nlohmann/detail/macro_scope.hpp>
13902
13903// #include <nlohmann/detail/output/output_adapters.hpp>
13904
13905
13906#include <algorithm> // copy
13907#include <cstddef> // size_t
13908#include <iterator> // back_inserter
13909#include <memory> // shared_ptr, make_shared
13910#include <string> // basic_string
13911#include <vector> // vector
13912
13913#ifndef JSON_NO_IO
13914 #include <ios> // streamsize
13915 #include <ostream> // basic_ostream
13916#endif // JSON_NO_IO
13917
13918// #include <nlohmann/detail/macro_scope.hpp>
13919
13920
13921namespace nlohmann
13922{
13923namespace detail
13924{
13926template<typename CharType> struct output_adapter_protocol
13927{
13928 virtual void write_character(CharType c) = 0;
13929 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13930 virtual ~output_adapter_protocol() = default;
13931
13936 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13937};
13938
13940template<typename CharType>
13941using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13942
13944template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13946{
13947 public:
13948 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13949 : v(vec)
13950 {}
13951
13952 void write_character(CharType c) override
13953 {
13954 v.push_back(c);
13955 }
13956
13958 void write_characters(const CharType* s, std::size_t length) override
13959 {
13960 std::copy(s, s + length, std::back_inserter(v));
13961 }
13962
13963 private:
13964 std::vector<CharType, AllocatorType>& v;
13965};
13966
13967#ifndef JSON_NO_IO
13969template<typename CharType>
13971{
13972 public:
13973 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13974 : stream(s)
13975 {}
13976
13977 void write_character(CharType c) override
13978 {
13979 stream.put(c);
13980 }
13981
13983 void write_characters(const CharType* s, std::size_t length) override
13984 {
13985 stream.write(s, static_cast<std::streamsize>(length));
13986 }
13987
13988 private:
13989 std::basic_ostream<CharType>& stream;
13990};
13991#endif // JSON_NO_IO
13992
13994template<typename CharType, typename StringType = std::basic_string<CharType>>
13996{
13997 public:
13998 explicit output_string_adapter(StringType& s) noexcept
13999 : str(s)
14000 {}
14001
14002 void write_character(CharType c) override
14003 {
14004 str.push_back(c);
14005 }
14006
14008 void write_characters(const CharType* s, std::size_t length) override
14009 {
14010 str.append(s, length);
14011 }
14012
14013 private:
14014 StringType& str;
14015};
14016
14017template<typename CharType, typename StringType = std::basic_string<CharType>>
14019{
14020 public:
14021 template<typename AllocatorType = std::allocator<CharType>>
14022 output_adapter(std::vector<CharType, AllocatorType>& vec)
14023 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14024
14025#ifndef JSON_NO_IO
14026 output_adapter(std::basic_ostream<CharType>& s)
14027 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14028#endif // JSON_NO_IO
14029
14030 output_adapter(StringType& s)
14031 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14032
14034 {
14035 return oa;
14036 }
14037
14038 private:
14039 output_adapter_t<CharType> oa = nullptr;
14040};
14041} // namespace detail
14042} // namespace nlohmann
14043
14044// #include <nlohmann/detail/string_concat.hpp>
14045
14046
14047namespace nlohmann
14048{
14049namespace detail
14050{
14052// binary writer //
14054
14058template<typename BasicJsonType, typename CharType>
14060{
14061 using string_t = typename BasicJsonType::string_t;
14062 using binary_t = typename BasicJsonType::binary_t;
14063 using number_float_t = typename BasicJsonType::number_float_t;
14064
14065 public:
14071 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14072 {
14073 JSON_ASSERT(oa);
14074 }
14075
14080 void write_bson(const BasicJsonType& j)
14081 {
14082 switch (j.type())
14083 {
14084 case value_t::object:
14085 {
14086 write_bson_object(*j.m_value.object);
14087 break;
14088 }
14089
14090 case value_t::null:
14091 case value_t::array:
14092 case value_t::string:
14093 case value_t::boolean:
14094 case value_t::number_integer:
14095 case value_t::number_unsigned:
14096 case value_t::number_float:
14097 case value_t::binary:
14098 case value_t::discarded:
14099 default:
14100 {
14101 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14102 }
14103 }
14104 }
14105
14109 void write_cbor(const BasicJsonType& j)
14110 {
14111 switch (j.type())
14112 {
14113 case value_t::null:
14114 {
14115 oa->write_character(to_char_type(0xF6));
14116 break;
14117 }
14118
14119 case value_t::boolean:
14120 {
14121 oa->write_character(j.m_value.boolean
14122 ? to_char_type(0xF5)
14123 : to_char_type(0xF4));
14124 break;
14125 }
14126
14127 case value_t::number_integer:
14128 {
14129 if (j.m_value.number_integer >= 0)
14130 {
14131 // CBOR does not differentiate between positive signed
14132 // integers and unsigned integers. Therefore, we used the
14133 // code from the value_t::number_unsigned case here.
14134 if (j.m_value.number_integer <= 0x17)
14135 {
14136 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14137 }
14138 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14139 {
14140 oa->write_character(to_char_type(0x18));
14141 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14142 }
14143 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
14144 {
14145 oa->write_character(to_char_type(0x19));
14146 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14147 }
14148 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
14149 {
14150 oa->write_character(to_char_type(0x1A));
14151 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14152 }
14153 else
14154 {
14155 oa->write_character(to_char_type(0x1B));
14156 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14157 }
14158 }
14159 else
14160 {
14161 // The conversions below encode the sign in the first
14162 // byte, and the value is converted to a positive number.
14163 const auto positive_number = -1 - j.m_value.number_integer;
14164 if (j.m_value.number_integer >= -24)
14165 {
14166 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
14167 }
14168 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
14169 {
14170 oa->write_character(to_char_type(0x38));
14171 write_number(static_cast<std::uint8_t>(positive_number));
14172 }
14173 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
14174 {
14175 oa->write_character(to_char_type(0x39));
14176 write_number(static_cast<std::uint16_t>(positive_number));
14177 }
14178 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
14179 {
14180 oa->write_character(to_char_type(0x3A));
14181 write_number(static_cast<std::uint32_t>(positive_number));
14182 }
14183 else
14184 {
14185 oa->write_character(to_char_type(0x3B));
14186 write_number(static_cast<std::uint64_t>(positive_number));
14187 }
14188 }
14189 break;
14190 }
14191
14192 case value_t::number_unsigned:
14193 {
14194 if (j.m_value.number_unsigned <= 0x17)
14195 {
14196 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14197 }
14198 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14199 {
14200 oa->write_character(to_char_type(0x18));
14201 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14202 }
14203 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14204 {
14205 oa->write_character(to_char_type(0x19));
14206 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
14207 }
14208 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14209 {
14210 oa->write_character(to_char_type(0x1A));
14211 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
14212 }
14213 else
14214 {
14215 oa->write_character(to_char_type(0x1B));
14216 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
14217 }
14218 break;
14219 }
14220
14221 case value_t::number_float:
14222 {
14223 if (std::isnan(j.m_value.number_float))
14224 {
14225 // NaN is 0xf97e00 in CBOR
14226 oa->write_character(to_char_type(0xF9));
14227 oa->write_character(to_char_type(0x7E));
14228 oa->write_character(to_char_type(0x00));
14229 }
14230 else if (std::isinf(j.m_value.number_float))
14231 {
14232 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
14233 oa->write_character(to_char_type(0xf9));
14234 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
14235 oa->write_character(to_char_type(0x00));
14236 }
14237 else
14238 {
14239 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
14240 }
14241 break;
14242 }
14243
14244 case value_t::string:
14245 {
14246 // step 1: write control byte and the string length
14247 const auto N = j.m_value.string->size();
14248 if (N <= 0x17)
14249 {
14250 write_number(static_cast<std::uint8_t>(0x60 + N));
14251 }
14252 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14253 {
14254 oa->write_character(to_char_type(0x78));
14255 write_number(static_cast<std::uint8_t>(N));
14256 }
14257 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14258 {
14259 oa->write_character(to_char_type(0x79));
14260 write_number(static_cast<std::uint16_t>(N));
14261 }
14262 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14263 {
14264 oa->write_character(to_char_type(0x7A));
14265 write_number(static_cast<std::uint32_t>(N));
14266 }
14267 // LCOV_EXCL_START
14268 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14269 {
14270 oa->write_character(to_char_type(0x7B));
14271 write_number(static_cast<std::uint64_t>(N));
14272 }
14273 // LCOV_EXCL_STOP
14274
14275 // step 2: write the string
14276 oa->write_characters(
14277 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14278 j.m_value.string->size());
14279 break;
14280 }
14281
14282 case value_t::array:
14283 {
14284 // step 1: write control byte and the array size
14285 const auto N = j.m_value.array->size();
14286 if (N <= 0x17)
14287 {
14288 write_number(static_cast<std::uint8_t>(0x80 + N));
14289 }
14290 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14291 {
14292 oa->write_character(to_char_type(0x98));
14293 write_number(static_cast<std::uint8_t>(N));
14294 }
14295 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14296 {
14297 oa->write_character(to_char_type(0x99));
14298 write_number(static_cast<std::uint16_t>(N));
14299 }
14300 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14301 {
14302 oa->write_character(to_char_type(0x9A));
14303 write_number(static_cast<std::uint32_t>(N));
14304 }
14305 // LCOV_EXCL_START
14306 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14307 {
14308 oa->write_character(to_char_type(0x9B));
14309 write_number(static_cast<std::uint64_t>(N));
14310 }
14311 // LCOV_EXCL_STOP
14312
14313 // step 2: write each element
14314 for (const auto& el : *j.m_value.array)
14315 {
14316 write_cbor(el);
14317 }
14318 break;
14319 }
14320
14321 case value_t::binary:
14322 {
14323 if (j.m_value.binary->has_subtype())
14324 {
14325 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
14326 {
14327 write_number(static_cast<std::uint8_t>(0xd8));
14328 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
14329 }
14330 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
14331 {
14332 write_number(static_cast<std::uint8_t>(0xd9));
14333 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
14334 }
14335 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
14336 {
14337 write_number(static_cast<std::uint8_t>(0xda));
14338 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
14339 }
14340 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
14341 {
14342 write_number(static_cast<std::uint8_t>(0xdb));
14343 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
14344 }
14345 }
14346
14347 // step 1: write control byte and the binary array size
14348 const auto N = j.m_value.binary->size();
14349 if (N <= 0x17)
14350 {
14351 write_number(static_cast<std::uint8_t>(0x40 + N));
14352 }
14353 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14354 {
14355 oa->write_character(to_char_type(0x58));
14356 write_number(static_cast<std::uint8_t>(N));
14357 }
14358 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14359 {
14360 oa->write_character(to_char_type(0x59));
14361 write_number(static_cast<std::uint16_t>(N));
14362 }
14363 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14364 {
14365 oa->write_character(to_char_type(0x5A));
14366 write_number(static_cast<std::uint32_t>(N));
14367 }
14368 // LCOV_EXCL_START
14369 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14370 {
14371 oa->write_character(to_char_type(0x5B));
14372 write_number(static_cast<std::uint64_t>(N));
14373 }
14374 // LCOV_EXCL_STOP
14375
14376 // step 2: write each element
14377 oa->write_characters(
14378 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14379 N);
14380
14381 break;
14382 }
14383
14384 case value_t::object:
14385 {
14386 // step 1: write control byte and the object size
14387 const auto N = j.m_value.object->size();
14388 if (N <= 0x17)
14389 {
14390 write_number(static_cast<std::uint8_t>(0xA0 + N));
14391 }
14392 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14393 {
14394 oa->write_character(to_char_type(0xB8));
14395 write_number(static_cast<std::uint8_t>(N));
14396 }
14397 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14398 {
14399 oa->write_character(to_char_type(0xB9));
14400 write_number(static_cast<std::uint16_t>(N));
14401 }
14402 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14403 {
14404 oa->write_character(to_char_type(0xBA));
14405 write_number(static_cast<std::uint32_t>(N));
14406 }
14407 // LCOV_EXCL_START
14408 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14409 {
14410 oa->write_character(to_char_type(0xBB));
14411 write_number(static_cast<std::uint64_t>(N));
14412 }
14413 // LCOV_EXCL_STOP
14414
14415 // step 2: write each element
14416 for (const auto& el : *j.m_value.object)
14417 {
14418 write_cbor(el.first);
14419 write_cbor(el.second);
14420 }
14421 break;
14422 }
14423
14424 case value_t::discarded:
14425 default:
14426 break;
14427 }
14428 }
14429
14433 void write_msgpack(const BasicJsonType& j)
14434 {
14435 switch (j.type())
14436 {
14437 case value_t::null: // nil
14438 {
14439 oa->write_character(to_char_type(0xC0));
14440 break;
14441 }
14442
14443 case value_t::boolean: // true and false
14444 {
14445 oa->write_character(j.m_value.boolean
14446 ? to_char_type(0xC3)
14447 : to_char_type(0xC2));
14448 break;
14449 }
14450
14451 case value_t::number_integer:
14452 {
14453 if (j.m_value.number_integer >= 0)
14454 {
14455 // MessagePack does not differentiate between positive
14456 // signed integers and unsigned integers. Therefore, we used
14457 // the code from the value_t::number_unsigned case here.
14458 if (j.m_value.number_unsigned < 128)
14459 {
14460 // positive fixnum
14461 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14462 }
14463 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14464 {
14465 // uint 8
14466 oa->write_character(to_char_type(0xCC));
14467 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14468 }
14469 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14470 {
14471 // uint 16
14472 oa->write_character(to_char_type(0xCD));
14473 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14474 }
14475 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14476 {
14477 // uint 32
14478 oa->write_character(to_char_type(0xCE));
14479 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14480 }
14481 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14482 {
14483 // uint 64
14484 oa->write_character(to_char_type(0xCF));
14485 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14486 }
14487 }
14488 else
14489 {
14490 if (j.m_value.number_integer >= -32)
14491 {
14492 // negative fixnum
14493 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14494 }
14495 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14496 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14497 {
14498 // int 8
14499 oa->write_character(to_char_type(0xD0));
14500 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14501 }
14502 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14503 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14504 {
14505 // int 16
14506 oa->write_character(to_char_type(0xD1));
14507 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14508 }
14509 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14510 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14511 {
14512 // int 32
14513 oa->write_character(to_char_type(0xD2));
14514 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14515 }
14516 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14517 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14518 {
14519 // int 64
14520 oa->write_character(to_char_type(0xD3));
14521 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14522 }
14523 }
14524 break;
14525 }
14526
14527 case value_t::number_unsigned:
14528 {
14529 if (j.m_value.number_unsigned < 128)
14530 {
14531 // positive fixnum
14532 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14533 }
14534 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14535 {
14536 // uint 8
14537 oa->write_character(to_char_type(0xCC));
14538 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14539 }
14540 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14541 {
14542 // uint 16
14543 oa->write_character(to_char_type(0xCD));
14544 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14545 }
14546 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14547 {
14548 // uint 32
14549 oa->write_character(to_char_type(0xCE));
14550 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14551 }
14552 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14553 {
14554 // uint 64
14555 oa->write_character(to_char_type(0xCF));
14556 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14557 }
14558 break;
14559 }
14560
14561 case value_t::number_float:
14562 {
14563 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14564 break;
14565 }
14566
14567 case value_t::string:
14568 {
14569 // step 1: write control byte and the string length
14570 const auto N = j.m_value.string->size();
14571 if (N <= 31)
14572 {
14573 // fixstr
14574 write_number(static_cast<std::uint8_t>(0xA0 | N));
14575 }
14576 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14577 {
14578 // str 8
14579 oa->write_character(to_char_type(0xD9));
14580 write_number(static_cast<std::uint8_t>(N));
14581 }
14582 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14583 {
14584 // str 16
14585 oa->write_character(to_char_type(0xDA));
14586 write_number(static_cast<std::uint16_t>(N));
14587 }
14588 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14589 {
14590 // str 32
14591 oa->write_character(to_char_type(0xDB));
14592 write_number(static_cast<std::uint32_t>(N));
14593 }
14594
14595 // step 2: write the string
14596 oa->write_characters(
14597 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14598 j.m_value.string->size());
14599 break;
14600 }
14601
14602 case value_t::array:
14603 {
14604 // step 1: write control byte and the array size
14605 const auto N = j.m_value.array->size();
14606 if (N <= 15)
14607 {
14608 // fixarray
14609 write_number(static_cast<std::uint8_t>(0x90 | N));
14610 }
14611 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14612 {
14613 // array 16
14614 oa->write_character(to_char_type(0xDC));
14615 write_number(static_cast<std::uint16_t>(N));
14616 }
14617 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14618 {
14619 // array 32
14620 oa->write_character(to_char_type(0xDD));
14621 write_number(static_cast<std::uint32_t>(N));
14622 }
14623
14624 // step 2: write each element
14625 for (const auto& el : *j.m_value.array)
14626 {
14627 write_msgpack(el);
14628 }
14629 break;
14630 }
14631
14632 case value_t::binary:
14633 {
14634 // step 0: determine if the binary type has a set subtype to
14635 // determine whether or not to use the ext or fixext types
14636 const bool use_ext = j.m_value.binary->has_subtype();
14637
14638 // step 1: write control byte and the byte string length
14639 const auto N = j.m_value.binary->size();
14640 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14641 {
14642 std::uint8_t output_type{};
14643 bool fixed = true;
14644 if (use_ext)
14645 {
14646 switch (N)
14647 {
14648 case 1:
14649 output_type = 0xD4; // fixext 1
14650 break;
14651 case 2:
14652 output_type = 0xD5; // fixext 2
14653 break;
14654 case 4:
14655 output_type = 0xD6; // fixext 4
14656 break;
14657 case 8:
14658 output_type = 0xD7; // fixext 8
14659 break;
14660 case 16:
14661 output_type = 0xD8; // fixext 16
14662 break;
14663 default:
14664 output_type = 0xC7; // ext 8
14665 fixed = false;
14666 break;
14667 }
14668
14669 }
14670 else
14671 {
14672 output_type = 0xC4; // bin 8
14673 fixed = false;
14674 }
14675
14676 oa->write_character(to_char_type(output_type));
14677 if (!fixed)
14678 {
14679 write_number(static_cast<std::uint8_t>(N));
14680 }
14681 }
14682 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14683 {
14684 std::uint8_t output_type = use_ext
14685 ? 0xC8 // ext 16
14686 : 0xC5; // bin 16
14687
14688 oa->write_character(to_char_type(output_type));
14689 write_number(static_cast<std::uint16_t>(N));
14690 }
14691 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14692 {
14693 std::uint8_t output_type = use_ext
14694 ? 0xC9 // ext 32
14695 : 0xC6; // bin 32
14696
14697 oa->write_character(to_char_type(output_type));
14698 write_number(static_cast<std::uint32_t>(N));
14699 }
14700
14701 // step 1.5: if this is an ext type, write the subtype
14702 if (use_ext)
14703 {
14704 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14705 }
14706
14707 // step 2: write the byte string
14708 oa->write_characters(
14709 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14710 N);
14711
14712 break;
14713 }
14714
14715 case value_t::object:
14716 {
14717 // step 1: write control byte and the object size
14718 const auto N = j.m_value.object->size();
14719 if (N <= 15)
14720 {
14721 // fixmap
14722 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14723 }
14724 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14725 {
14726 // map 16
14727 oa->write_character(to_char_type(0xDE));
14728 write_number(static_cast<std::uint16_t>(N));
14729 }
14730 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14731 {
14732 // map 32
14733 oa->write_character(to_char_type(0xDF));
14734 write_number(static_cast<std::uint32_t>(N));
14735 }
14736
14737 // step 2: write each element
14738 for (const auto& el : *j.m_value.object)
14739 {
14740 write_msgpack(el.first);
14741 write_msgpack(el.second);
14742 }
14743 break;
14744 }
14745
14746 case value_t::discarded:
14747 default:
14748 break;
14749 }
14750 }
14751
14759 void write_ubjson(const BasicJsonType& j, const bool use_count,
14760 const bool use_type, const bool add_prefix = true,
14761 const bool use_bjdata = false)
14762 {
14763 switch (j.type())
14764 {
14765 case value_t::null:
14766 {
14767 if (add_prefix)
14768 {
14769 oa->write_character(to_char_type('Z'));
14770 }
14771 break;
14772 }
14773
14774 case value_t::boolean:
14775 {
14776 if (add_prefix)
14777 {
14778 oa->write_character(j.m_value.boolean
14779 ? to_char_type('T')
14780 : to_char_type('F'));
14781 }
14782 break;
14783 }
14784
14785 case value_t::number_integer:
14786 {
14787 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
14788 break;
14789 }
14790
14791 case value_t::number_unsigned:
14792 {
14793 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
14794 break;
14795 }
14796
14797 case value_t::number_float:
14798 {
14799 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
14800 break;
14801 }
14802
14803 case value_t::string:
14804 {
14805 if (add_prefix)
14806 {
14807 oa->write_character(to_char_type('S'));
14808 }
14809 write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
14810 oa->write_characters(
14811 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14812 j.m_value.string->size());
14813 break;
14814 }
14815
14816 case value_t::array:
14817 {
14818 if (add_prefix)
14819 {
14820 oa->write_character(to_char_type('['));
14821 }
14822
14823 bool prefix_required = true;
14824 if (use_type && !j.m_value.array->empty())
14825 {
14826 JSON_ASSERT(use_count);
14827 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
14828 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14829 [this, first_prefix, use_bjdata](const BasicJsonType & v)
14830 {
14831 return ubjson_prefix(v, use_bjdata) == first_prefix;
14832 });
14833
14834 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
14835
14836 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
14837 {
14838 prefix_required = false;
14839 oa->write_character(to_char_type('$'));
14840 oa->write_character(first_prefix);
14841 }
14842 }
14843
14844 if (use_count)
14845 {
14846 oa->write_character(to_char_type('#'));
14847 write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
14848 }
14849
14850 for (const auto& el : *j.m_value.array)
14851 {
14852 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
14853 }
14854
14855 if (!use_count)
14856 {
14857 oa->write_character(to_char_type(']'));
14858 }
14859
14860 break;
14861 }
14862
14863 case value_t::binary:
14864 {
14865 if (add_prefix)
14866 {
14867 oa->write_character(to_char_type('['));
14868 }
14869
14870 if (use_type && !j.m_value.binary->empty())
14871 {
14872 JSON_ASSERT(use_count);
14873 oa->write_character(to_char_type('$'));
14874 oa->write_character('U');
14875 }
14876
14877 if (use_count)
14878 {
14879 oa->write_character(to_char_type('#'));
14880 write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
14881 }
14882
14883 if (use_type)
14884 {
14885 oa->write_characters(
14886 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14887 j.m_value.binary->size());
14888 }
14889 else
14890 {
14891 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14892 {
14893 oa->write_character(to_char_type('U'));
14894 oa->write_character(j.m_value.binary->data()[i]);
14895 }
14896 }
14897
14898 if (!use_count)
14899 {
14900 oa->write_character(to_char_type(']'));
14901 }
14902
14903 break;
14904 }
14905
14906 case value_t::object:
14907 {
14908 if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
14909 {
14910 if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
14911 {
14912 break;
14913 }
14914 }
14915
14916 if (add_prefix)
14917 {
14918 oa->write_character(to_char_type('{'));
14919 }
14920
14921 bool prefix_required = true;
14922 if (use_type && !j.m_value.object->empty())
14923 {
14924 JSON_ASSERT(use_count);
14925 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
14926 const bool same_prefix = std::all_of(j.begin(), j.end(),
14927 [this, first_prefix, use_bjdata](const BasicJsonType & v)
14928 {
14929 return ubjson_prefix(v, use_bjdata) == first_prefix;
14930 });
14931
14932 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
14933
14934 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
14935 {
14936 prefix_required = false;
14937 oa->write_character(to_char_type('$'));
14938 oa->write_character(first_prefix);
14939 }
14940 }
14941
14942 if (use_count)
14943 {
14944 oa->write_character(to_char_type('#'));
14945 write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
14946 }
14947
14948 for (const auto& el : *j.m_value.object)
14949 {
14950 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
14951 oa->write_characters(
14952 reinterpret_cast<const CharType*>(el.first.c_str()),
14953 el.first.size());
14954 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
14955 }
14956
14957 if (!use_count)
14958 {
14959 oa->write_character(to_char_type('}'));
14960 }
14961
14962 break;
14963 }
14964
14965 case value_t::discarded:
14966 default:
14967 break;
14968 }
14969 }
14970
14971 private:
14973 // BSON //
14975
14980 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14981 {
14982 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14983 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14984 {
14985 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
14986 static_cast<void>(j);
14987 }
14988
14989 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14990 }
14991
14995 void write_bson_entry_header(const string_t& name,
14996 const std::uint8_t element_type)
14997 {
14998 oa->write_character(to_char_type(element_type)); // boolean
14999 oa->write_characters(
15000 reinterpret_cast<const CharType*>(name.c_str()),
15001 name.size() + 1u);
15002 }
15003
15007 void write_bson_boolean(const string_t& name,
15008 const bool value)
15009 {
15010 write_bson_entry_header(name, 0x08);
15011 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15012 }
15013
15017 void write_bson_double(const string_t& name,
15018 const double value)
15019 {
15020 write_bson_entry_header(name, 0x01);
15021 write_number<double>(value, true);
15022 }
15023
15027 static std::size_t calc_bson_string_size(const string_t& value)
15028 {
15029 return sizeof(std::int32_t) + value.size() + 1ul;
15030 }
15031
15035 void write_bson_string(const string_t& name,
15036 const string_t& value)
15037 {
15038 write_bson_entry_header(name, 0x02);
15039
15040 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15041 oa->write_characters(
15042 reinterpret_cast<const CharType*>(value.c_str()),
15043 value.size() + 1);
15044 }
15045
15049 void write_bson_null(const string_t& name)
15050 {
15051 write_bson_entry_header(name, 0x0A);
15052 }
15053
15057 static std::size_t calc_bson_integer_size(const std::int64_t value)
15058 {
15059 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15060 ? sizeof(std::int32_t)
15061 : sizeof(std::int64_t);
15062 }
15063
15067 void write_bson_integer(const string_t& name,
15068 const std::int64_t value)
15069 {
15070 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
15071 {
15072 write_bson_entry_header(name, 0x10); // int32
15073 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15074 }
15075 else
15076 {
15077 write_bson_entry_header(name, 0x12); // int64
15078 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15079 }
15080 }
15081
15085 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15086 {
15087 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15088 ? sizeof(std::int32_t)
15089 : sizeof(std::int64_t);
15090 }
15091
15095 void write_bson_unsigned(const string_t& name,
15096 const BasicJsonType& j)
15097 {
15098 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15099 {
15100 write_bson_entry_header(name, 0x10 /* int32 */);
15101 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15102 }
15103 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15104 {
15105 write_bson_entry_header(name, 0x12 /* int64 */);
15106 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
15107 }
15108 else
15109 {
15110 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
15111 }
15112 }
15113
15117 void write_bson_object_entry(const string_t& name,
15118 const typename BasicJsonType::object_t& value)
15119 {
15120 write_bson_entry_header(name, 0x03); // object
15121 write_bson_object(value);
15122 }
15123
15127 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
15128 {
15129 std::size_t array_index = 0ul;
15130
15131 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
15132 {
15133 return result + calc_bson_element_size(std::to_string(array_index++), el);
15134 });
15135
15136 return sizeof(std::int32_t) + embedded_document_size + 1ul;
15137 }
15138
15142 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
15143 {
15144 return sizeof(std::int32_t) + value.size() + 1ul;
15145 }
15146
15150 void write_bson_array(const string_t& name,
15151 const typename BasicJsonType::array_t& value)
15152 {
15153 write_bson_entry_header(name, 0x04); // array
15154 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
15155
15156 std::size_t array_index = 0ul;
15157
15158 for (const auto& el : value)
15159 {
15160 write_bson_element(std::to_string(array_index++), el);
15161 }
15162
15163 oa->write_character(to_char_type(0x00));
15164 }
15165
15169 void write_bson_binary(const string_t& name,
15170 const binary_t& value)
15171 {
15172 write_bson_entry_header(name, 0x05);
15173
15174 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
15175 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
15176
15177 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
15178 }
15179
15184 static std::size_t calc_bson_element_size(const string_t& name,
15185 const BasicJsonType& j)
15186 {
15187 const auto header_size = calc_bson_entry_header_size(name, j);
15188 switch (j.type())
15189 {
15190 case value_t::object:
15191 return header_size + calc_bson_object_size(*j.m_value.object);
15192
15193 case value_t::array:
15194 return header_size + calc_bson_array_size(*j.m_value.array);
15195
15196 case value_t::binary:
15197 return header_size + calc_bson_binary_size(*j.m_value.binary);
15198
15199 case value_t::boolean:
15200 return header_size + 1ul;
15201
15202 case value_t::number_float:
15203 return header_size + 8ul;
15204
15205 case value_t::number_integer:
15206 return header_size + calc_bson_integer_size(j.m_value.number_integer);
15207
15208 case value_t::number_unsigned:
15209 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
15210
15211 case value_t::string:
15212 return header_size + calc_bson_string_size(*j.m_value.string);
15213
15214 case value_t::null:
15215 return header_size + 0ul;
15216
15217 // LCOV_EXCL_START
15218 case value_t::discarded:
15219 default:
15220 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15221 return 0ul;
15222 // LCOV_EXCL_STOP
15223 }
15224 }
15225
15232 void write_bson_element(const string_t& name,
15233 const BasicJsonType& j)
15234 {
15235 switch (j.type())
15236 {
15237 case value_t::object:
15238 return write_bson_object_entry(name, *j.m_value.object);
15239
15240 case value_t::array:
15241 return write_bson_array(name, *j.m_value.array);
15242
15243 case value_t::binary:
15244 return write_bson_binary(name, *j.m_value.binary);
15245
15246 case value_t::boolean:
15247 return write_bson_boolean(name, j.m_value.boolean);
15248
15249 case value_t::number_float:
15250 return write_bson_double(name, j.m_value.number_float);
15251
15252 case value_t::number_integer:
15253 return write_bson_integer(name, j.m_value.number_integer);
15254
15255 case value_t::number_unsigned:
15256 return write_bson_unsigned(name, j);
15257
15258 case value_t::string:
15259 return write_bson_string(name, *j.m_value.string);
15260
15261 case value_t::null:
15262 return write_bson_null(name);
15263
15264 // LCOV_EXCL_START
15265 case value_t::discarded:
15266 default:
15267 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15268 return;
15269 // LCOV_EXCL_STOP
15270 }
15271 }
15272
15279 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
15280 {
15281 std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
15282 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
15283 {
15284 return result += calc_bson_element_size(el.first, el.second);
15285 });
15286
15287 return sizeof(std::int32_t) + document_size + 1ul;
15288 }
15289
15294 void write_bson_object(const typename BasicJsonType::object_t& value)
15295 {
15296 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
15297
15298 for (const auto& el : value)
15299 {
15300 write_bson_element(el.first, el.second);
15301 }
15302
15303 oa->write_character(to_char_type(0x00));
15304 }
15305
15307 // CBOR //
15309
15310 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
15311 {
15312 return to_char_type(0xFA); // Single-Precision Float
15313 }
15314
15315 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
15316 {
15317 return to_char_type(0xFB); // Double-Precision Float
15318 }
15319
15321 // MsgPack //
15323
15324 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
15325 {
15326 return to_char_type(0xCA); // float 32
15327 }
15328
15329 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
15330 {
15331 return to_char_type(0xCB); // float 64
15332 }
15333
15335 // UBJSON //
15337
15338 // UBJSON: write number (floating point)
15339 template<typename NumberType, typename std::enable_if<
15340 std::is_floating_point<NumberType>::value, int>::type = 0>
15341 void write_number_with_ubjson_prefix(const NumberType n,
15342 const bool add_prefix,
15343 const bool use_bjdata)
15344 {
15345 if (add_prefix)
15346 {
15347 oa->write_character(get_ubjson_float_prefix(n));
15348 }
15349 write_number(n, use_bjdata);
15350 }
15351
15352 // UBJSON: write number (unsigned integer)
15353 template<typename NumberType, typename std::enable_if<
15354 std::is_unsigned<NumberType>::value, int>::type = 0>
15355 void write_number_with_ubjson_prefix(const NumberType n,
15356 const bool add_prefix,
15357 const bool use_bjdata)
15358 {
15359 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15360 {
15361 if (add_prefix)
15362 {
15363 oa->write_character(to_char_type('i')); // int8
15364 }
15365 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15366 }
15367 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
15368 {
15369 if (add_prefix)
15370 {
15371 oa->write_character(to_char_type('U')); // uint8
15372 }
15373 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15374 }
15375 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15376 {
15377 if (add_prefix)
15378 {
15379 oa->write_character(to_char_type('I')); // int16
15380 }
15381 write_number(static_cast<std::int16_t>(n), use_bjdata);
15382 }
15383 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
15384 {
15385 if (add_prefix)
15386 {
15387 oa->write_character(to_char_type('u')); // uint16 - bjdata only
15388 }
15389 write_number(static_cast<std::uint16_t>(n), use_bjdata);
15390 }
15391 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15392 {
15393 if (add_prefix)
15394 {
15395 oa->write_character(to_char_type('l')); // int32
15396 }
15397 write_number(static_cast<std::int32_t>(n), use_bjdata);
15398 }
15399 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
15400 {
15401 if (add_prefix)
15402 {
15403 oa->write_character(to_char_type('m')); // uint32 - bjdata only
15404 }
15405 write_number(static_cast<std::uint32_t>(n), use_bjdata);
15406 }
15407 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15408 {
15409 if (add_prefix)
15410 {
15411 oa->write_character(to_char_type('L')); // int64
15412 }
15413 write_number(static_cast<std::int64_t>(n), use_bjdata);
15414 }
15415 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
15416 {
15417 if (add_prefix)
15418 {
15419 oa->write_character(to_char_type('M')); // uint64 - bjdata only
15420 }
15421 write_number(static_cast<std::uint64_t>(n), use_bjdata);
15422 }
15423 else
15424 {
15425 if (add_prefix)
15426 {
15427 oa->write_character(to_char_type('H')); // high-precision number
15428 }
15429
15430 const auto number = BasicJsonType(n).dump();
15431 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15432 for (std::size_t i = 0; i < number.size(); ++i)
15433 {
15434 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15435 }
15436 }
15437 }
15438
15439 // UBJSON: write number (signed integer)
15440 template < typename NumberType, typename std::enable_if <
15441 std::is_signed<NumberType>::value&&
15442 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15443 void write_number_with_ubjson_prefix(const NumberType n,
15444 const bool add_prefix,
15445 const bool use_bjdata)
15446 {
15447 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15448 {
15449 if (add_prefix)
15450 {
15451 oa->write_character(to_char_type('i')); // int8
15452 }
15453 write_number(static_cast<std::int8_t>(n), use_bjdata);
15454 }
15455 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15456 {
15457 if (add_prefix)
15458 {
15459 oa->write_character(to_char_type('U')); // uint8
15460 }
15461 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15462 }
15463 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15464 {
15465 if (add_prefix)
15466 {
15467 oa->write_character(to_char_type('I')); // int16
15468 }
15469 write_number(static_cast<std::int16_t>(n), use_bjdata);
15470 }
15471 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
15472 {
15473 if (add_prefix)
15474 {
15475 oa->write_character(to_char_type('u')); // uint16 - bjdata only
15476 }
15477 write_number(static_cast<uint16_t>(n), use_bjdata);
15478 }
15479 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15480 {
15481 if (add_prefix)
15482 {
15483 oa->write_character(to_char_type('l')); // int32
15484 }
15485 write_number(static_cast<std::int32_t>(n), use_bjdata);
15486 }
15487 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
15488 {
15489 if (add_prefix)
15490 {
15491 oa->write_character(to_char_type('m')); // uint32 - bjdata only
15492 }
15493 write_number(static_cast<uint32_t>(n), use_bjdata);
15494 }
15495 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15496 {
15497 if (add_prefix)
15498 {
15499 oa->write_character(to_char_type('L')); // int64
15500 }
15501 write_number(static_cast<std::int64_t>(n), use_bjdata);
15502 }
15503 // LCOV_EXCL_START
15504 else
15505 {
15506 if (add_prefix)
15507 {
15508 oa->write_character(to_char_type('H')); // high-precision number
15509 }
15510
15511 const auto number = BasicJsonType(n).dump();
15512 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15513 for (std::size_t i = 0; i < number.size(); ++i)
15514 {
15515 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15516 }
15517 }
15518 // LCOV_EXCL_STOP
15519 }
15520
15524 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
15525 {
15526 switch (j.type())
15527 {
15528 case value_t::null:
15529 return 'Z';
15530
15531 case value_t::boolean:
15532 return j.m_value.boolean ? 'T' : 'F';
15533
15534 case value_t::number_integer:
15535 {
15536 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15537 {
15538 return 'i';
15539 }
15540 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15541 {
15542 return 'U';
15543 }
15544 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15545 {
15546 return 'I';
15547 }
15548 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
15549 {
15550 return 'u';
15551 }
15552 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15553 {
15554 return 'l';
15555 }
15556 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
15557 {
15558 return 'm';
15559 }
15560 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15561 {
15562 return 'L';
15563 }
15564 // anything else is treated as high-precision number
15565 return 'H'; // LCOV_EXCL_LINE
15566 }
15567
15568 case value_t::number_unsigned:
15569 {
15570 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15571 {
15572 return 'i';
15573 }
15574 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15575 {
15576 return 'U';
15577 }
15578 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15579 {
15580 return 'I';
15581 }
15582 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
15583 {
15584 return 'u';
15585 }
15586 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15587 {
15588 return 'l';
15589 }
15590 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
15591 {
15592 return 'm';
15593 }
15594 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15595 {
15596 return 'L';
15597 }
15598 if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15599 {
15600 return 'M';
15601 }
15602 // anything else is treated as high-precision number
15603 return 'H'; // LCOV_EXCL_LINE
15604 }
15605
15606 case value_t::number_float:
15607 return get_ubjson_float_prefix(j.m_value.number_float);
15608
15609 case value_t::string:
15610 return 'S';
15611
15612 case value_t::array: // fallthrough
15613 case value_t::binary:
15614 return '[';
15615
15616 case value_t::object:
15617 return '{';
15618
15619 case value_t::discarded:
15620 default: // discarded values
15621 return 'N';
15622 }
15623 }
15624
15625 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15626 {
15627 return 'd'; // float 32
15628 }
15629
15630 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15631 {
15632 return 'D'; // float 64
15633 }
15634
15638 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
15639 {
15640 std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
15641 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
15642 };
15643
15644 string_t key = "_ArrayType_";
15645 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
15646 if (it == bjdtype.end())
15647 {
15648 return true;
15649 }
15650 CharType dtype = it->second;
15651
15652 key = "_ArraySize_";
15653 std::size_t len = (value.at(key).empty() ? 0 : 1);
15654 for (const auto& el : value.at(key))
15655 {
15656 len *= static_cast<std::size_t>(el.m_value.number_unsigned);
15657 }
15658
15659 key = "_ArrayData_";
15660 if (value.at(key).size() != len)
15661 {
15662 return true;
15663 }
15664
15665 oa->write_character('[');
15666 oa->write_character('$');
15667 oa->write_character(dtype);
15668 oa->write_character('#');
15669
15670 key = "_ArraySize_";
15671 write_ubjson(value.at(key), use_count, use_type, true, true);
15672
15673 key = "_ArrayData_";
15674 if (dtype == 'U' || dtype == 'C')
15675 {
15676 for (const auto& el : value.at(key))
15677 {
15678 write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
15679 }
15680 }
15681 else if (dtype == 'i')
15682 {
15683 for (const auto& el : value.at(key))
15684 {
15685 write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
15686 }
15687 }
15688 else if (dtype == 'u')
15689 {
15690 for (const auto& el : value.at(key))
15691 {
15692 write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
15693 }
15694 }
15695 else if (dtype == 'I')
15696 {
15697 for (const auto& el : value.at(key))
15698 {
15699 write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
15700 }
15701 }
15702 else if (dtype == 'm')
15703 {
15704 for (const auto& el : value.at(key))
15705 {
15706 write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
15707 }
15708 }
15709 else if (dtype == 'l')
15710 {
15711 for (const auto& el : value.at(key))
15712 {
15713 write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
15714 }
15715 }
15716 else if (dtype == 'M')
15717 {
15718 for (const auto& el : value.at(key))
15719 {
15720 write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
15721 }
15722 }
15723 else if (dtype == 'L')
15724 {
15725 for (const auto& el : value.at(key))
15726 {
15727 write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
15728 }
15729 }
15730 else if (dtype == 'd')
15731 {
15732 for (const auto& el : value.at(key))
15733 {
15734 write_number(static_cast<float>(el.m_value.number_float), true);
15735 }
15736 }
15737 else if (dtype == 'D')
15738 {
15739 for (const auto& el : value.at(key))
15740 {
15741 write_number(static_cast<double>(el.m_value.number_float), true);
15742 }
15743 }
15744 return false;
15745 }
15746
15748 // Utility functions //
15750
15751 /*
15752 @brief write a number to output input
15753 @param[in] n number of type @a NumberType
15754 @param[in] OutputIsLittleEndian Set to true if output data is
15755 required to be little endian
15756 @tparam NumberType the type of the number
15757
15758 @note This function needs to respect the system's endianness, because bytes
15759 in CBOR, MessagePack, and UBJSON are stored in network order (big
15760 endian) and therefore need reordering on little endian systems.
15761 On the other hand, BSON and BJData use little endian and should reorder
15762 on big endian systems.
15763 */
15764 template<typename NumberType>
15765 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
15766 {
15767 // step 1: write number to array of length NumberType
15768 std::array<CharType, sizeof(NumberType)> vec{};
15769 std::memcpy(vec.data(), &n, sizeof(NumberType));
15770
15771 // step 2: write array to output (with possible reordering)
15772 if (is_little_endian != OutputIsLittleEndian)
15773 {
15774 // reverse byte order prior to conversion if necessary
15775 std::reverse(vec.begin(), vec.end());
15776 }
15777
15778 oa->write_characters(vec.data(), sizeof(NumberType));
15779 }
15780
15781 void write_compact_float(const number_float_t n, detail::input_format_t format)
15782 {
15783#ifdef __GNUC__
15784#pragma GCC diagnostic push
15785#pragma GCC diagnostic ignored "-Wfloat-equal"
15786#endif
15787 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15788 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15789 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15790 {
15791 oa->write_character(format == detail::input_format_t::cbor
15792 ? get_cbor_float_prefix(static_cast<float>(n))
15793 : get_msgpack_float_prefix(static_cast<float>(n)));
15794 write_number(static_cast<float>(n));
15795 }
15796 else
15797 {
15798 oa->write_character(format == detail::input_format_t::cbor
15799 ? get_cbor_float_prefix(n)
15800 : get_msgpack_float_prefix(n));
15801 write_number(n);
15802 }
15803#ifdef __GNUC__
15804#pragma GCC diagnostic pop
15805#endif
15806 }
15807
15808 public:
15809 // The following to_char_type functions are implement the conversion
15810 // between uint8_t and CharType. In case CharType is not unsigned,
15811 // such a conversion is required to allow values greater than 128.
15812 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15813 template < typename C = CharType,
15814 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15815 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15816 {
15817 return *reinterpret_cast<char*>(&x);
15818 }
15819
15820 template < typename C = CharType,
15821 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15822 static CharType to_char_type(std::uint8_t x) noexcept
15823 {
15824 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15825 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15826 CharType result;
15827 std::memcpy(&result, &x, sizeof(x));
15828 return result;
15829 }
15830
15831 template<typename C = CharType,
15833 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15834 {
15835 return x;
15836 }
15837
15838 template < typename InputCharType, typename C = CharType,
15839 enable_if_t <
15840 std::is_signed<C>::value &&
15841 std::is_signed<char>::value &&
15842 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15843 > * = nullptr >
15844 static constexpr CharType to_char_type(InputCharType x) noexcept
15845 {
15846 return x;
15847 }
15848
15849 private:
15851 const bool is_little_endian = little_endianness();
15852
15854 output_adapter_t<CharType> oa = nullptr;
15855};
15856} // namespace detail
15857} // namespace nlohmann
15858
15859// #include <nlohmann/detail/output/output_adapters.hpp>
15860
15861// #include <nlohmann/detail/output/serializer.hpp>
15862
15863
15864#include <algorithm> // reverse, remove, fill, find, none_of
15865#include <array> // array
15866#include <clocale> // localeconv, lconv
15867#include <cmath> // labs, isfinite, isnan, signbit
15868#include <cstddef> // size_t, ptrdiff_t
15869#include <cstdint> // uint8_t
15870#include <cstdio> // snprintf
15871#include <limits> // numeric_limits
15872#include <string> // string, char_traits
15873#include <iomanip> // setfill, setw
15874#include <type_traits> // is_same
15875#include <utility> // move
15876
15877// #include <nlohmann/detail/conversions/to_chars.hpp>
15878
15879
15880#include <array> // array
15881#include <cmath> // signbit, isfinite
15882#include <cstdint> // intN_t, uintN_t
15883#include <cstring> // memcpy, memmove
15884#include <limits> // numeric_limits
15885#include <type_traits> // conditional
15886
15887// #include <nlohmann/detail/macro_scope.hpp>
15888
15889
15890namespace nlohmann
15891{
15892namespace detail
15893{
15894
15914namespace dtoa_impl
15915{
15916
15917template<typename Target, typename Source>
15918Target reinterpret_bits(const Source source)
15919{
15920 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15921
15922 Target target;
15923 std::memcpy(&target, &source, sizeof(Source));
15924 return target;
15925}
15926
15927struct diyfp // f * 2^e
15928{
15929 static constexpr int kPrecision = 64; // = q
15930
15931 std::uint64_t f = 0;
15932 int e = 0;
15933
15934 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15935
15940 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15941 {
15942 JSON_ASSERT(x.e == y.e);
15943 JSON_ASSERT(x.f >= y.f);
15944
15945 return {x.f - y.f, x.e};
15946 }
15947
15952 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15953 {
15954 static_assert(kPrecision == 64, "internal error");
15955
15956 // Computes:
15957 // f = round((x.f * y.f) / 2^q)
15958 // e = x.e + y.e + q
15959
15960 // Emulate the 64-bit * 64-bit multiplication:
15961 //
15962 // p = u * v
15963 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15964 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15965 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15966 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15967 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15968 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15969 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15970 //
15971 // (Since Q might be larger than 2^32 - 1)
15972 //
15973 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15974 //
15975 // (Q_hi + H does not overflow a 64-bit int)
15976 //
15977 // = p_lo + 2^64 p_hi
15978
15979 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15980 const std::uint64_t u_hi = x.f >> 32u;
15981 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15982 const std::uint64_t v_hi = y.f >> 32u;
15983
15984 const std::uint64_t p0 = u_lo * v_lo;
15985 const std::uint64_t p1 = u_lo * v_hi;
15986 const std::uint64_t p2 = u_hi * v_lo;
15987 const std::uint64_t p3 = u_hi * v_hi;
15988
15989 const std::uint64_t p0_hi = p0 >> 32u;
15990 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15991 const std::uint64_t p1_hi = p1 >> 32u;
15992 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15993 const std::uint64_t p2_hi = p2 >> 32u;
15994
15995 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15996
15997 // The full product might now be computed as
15998 //
15999 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16000 // p_lo = p0_lo + (Q << 32)
16001 //
16002 // But in this particular case here, the full p_lo is not required.
16003 // Effectively we only need to add the highest bit in p_lo to p_hi (and
16004 // Q_hi + 1 does not overflow).
16005
16006 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
16007
16008 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16009
16010 return {h, x.e + y.e + 64};
16011 }
16012
16017 static diyfp normalize(diyfp x) noexcept
16018 {
16019 JSON_ASSERT(x.f != 0);
16020
16021 while ((x.f >> 63u) == 0)
16022 {
16023 x.f <<= 1u;
16024 x.e--;
16025 }
16026
16027 return x;
16028 }
16029
16034 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16035 {
16036 const int delta = x.e - target_exponent;
16037
16038 JSON_ASSERT(delta >= 0);
16039 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16040
16041 return {x.f << delta, target_exponent};
16042 }
16043};
16044
16046{
16050};
16051
16058template<typename FloatType>
16060{
16061 JSON_ASSERT(std::isfinite(value));
16062 JSON_ASSERT(value > 0);
16063
16064 // Convert the IEEE representation into a diyfp.
16065 //
16066 // If v is denormal:
16067 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16068 // If v is normalized:
16069 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16070
16071 static_assert(std::numeric_limits<FloatType>::is_iec559,
16072 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16073
16074 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16075 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16076 constexpr int kMinExp = 1 - kBias;
16077 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
16078
16079 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
16080
16081 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16082 const std::uint64_t E = bits >> (kPrecision - 1);
16083 const std::uint64_t F = bits & (kHiddenBit - 1);
16084
16085 const bool is_denormal = E == 0;
16086 const diyfp v = is_denormal
16087 ? diyfp(F, kMinExp)
16088 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
16089
16090 // Compute the boundaries m- and m+ of the floating-point value
16091 // v = f * 2^e.
16092 //
16093 // Determine v- and v+, the floating-point predecessor and successor if v,
16094 // respectively.
16095 //
16096 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
16097 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
16098 //
16099 // v+ = v + 2^e
16100 //
16101 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
16102 // between m- and m+ round to v, regardless of how the input rounding
16103 // algorithm breaks ties.
16104 //
16105 // ---+-------------+-------------+-------------+-------------+--- (A)
16106 // v- m- v m+ v+
16107 //
16108 // -----------------+------+------+-------------+-------------+--- (B)
16109 // v- m- v m+ v+
16110
16111 const bool lower_boundary_is_closer = F == 0 && E > 1;
16112 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
16113 const diyfp m_minus = lower_boundary_is_closer
16114 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
16115 : diyfp(2 * v.f - 1, v.e - 1); // (A)
16116
16117 // Determine the normalized w+ = m+.
16118 const diyfp w_plus = diyfp::normalize(m_plus);
16119
16120 // Determine w- = m- such that e_(w-) = e_(w+).
16121 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
16122
16123 return {diyfp::normalize(v), w_minus, w_plus};
16124}
16125
16126// Given normalized diyfp w, Grisu needs to find a (normalized) cached
16127// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
16128// within a certain range [alpha, gamma] (Definition 3.2 from [1])
16129//
16130// alpha <= e = e_c + e_w + q <= gamma
16131//
16132// or
16133//
16134// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
16135// <= f_c * f_w * 2^gamma
16136//
16137// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
16138//
16139// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
16140//
16141// or
16142//
16143// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
16144//
16145// The choice of (alpha,gamma) determines the size of the table and the form of
16146// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
16147// in practice:
16148//
16149// The idea is to cut the number c * w = f * 2^e into two parts, which can be
16150// processed independently: An integral part p1, and a fractional part p2:
16151//
16152// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
16153// = (f div 2^-e) + (f mod 2^-e) * 2^e
16154// = p1 + p2 * 2^e
16155//
16156// The conversion of p1 into decimal form requires a series of divisions and
16157// modulos by (a power of) 10. These operations are faster for 32-bit than for
16158// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
16159// achieved by choosing
16160//
16161// -e >= 32 or e <= -32 := gamma
16162//
16163// In order to convert the fractional part
16164//
16165// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
16166//
16167// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
16168// d[-i] are extracted in order:
16169//
16170// (10 * p2) div 2^-e = d[-1]
16171// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
16172//
16173// The multiplication by 10 must not overflow. It is sufficient to choose
16174//
16175// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
16176//
16177// Since p2 = f mod 2^-e < 2^-e,
16178//
16179// -e <= 60 or e >= -60 := alpha
16180
16181constexpr int kAlpha = -60;
16182constexpr int kGamma = -32;
16183
16184struct cached_power // c = f * 2^e ~= 10^k
16185{
16186 std::uint64_t f;
16187 int e;
16188 int k;
16189};
16190
16199{
16200 // Now
16201 //
16202 // alpha <= e_c + e + q <= gamma (1)
16203 // ==> f_c * 2^alpha <= c * 2^e * 2^q
16204 //
16205 // and since the c's are normalized, 2^(q-1) <= f_c,
16206 //
16207 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
16208 // ==> 2^(alpha - e - 1) <= c
16209 //
16210 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
16211 //
16212 // k = ceil( log_10( 2^(alpha - e - 1) ) )
16213 // = ceil( (alpha - e - 1) * log_10(2) )
16214 //
16215 // From the paper:
16216 // "In theory the result of the procedure could be wrong since c is rounded,
16217 // and the computation itself is approximated [...]. In practice, however,
16218 // this simple function is sufficient."
16219 //
16220 // For IEEE double precision floating-point numbers converted into
16221 // normalized diyfp's w = f * 2^e, with q = 64,
16222 //
16223 // e >= -1022 (min IEEE exponent)
16224 // -52 (p - 1)
16225 // -52 (p - 1, possibly normalize denormal IEEE numbers)
16226 // -11 (normalize the diyfp)
16227 // = -1137
16228 //
16229 // and
16230 //
16231 // e <= +1023 (max IEEE exponent)
16232 // -52 (p - 1)
16233 // -11 (normalize the diyfp)
16234 // = 960
16235 //
16236 // This binary exponent range [-1137,960] results in a decimal exponent
16237 // range [-307,324]. One does not need to store a cached power for each
16238 // k in this range. For each such k it suffices to find a cached power
16239 // such that the exponent of the product lies in [alpha,gamma].
16240 // This implies that the difference of the decimal exponents of adjacent
16241 // table entries must be less than or equal to
16242 //
16243 // floor( (gamma - alpha) * log_10(2) ) = 8.
16244 //
16245 // (A smaller distance gamma-alpha would require a larger table.)
16246
16247 // NB:
16248 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
16249
16250 constexpr int kCachedPowersMinDecExp = -300;
16251 constexpr int kCachedPowersDecStep = 8;
16252
16253 static constexpr std::array<cached_power, 79> kCachedPowers =
16254 {
16255 {
16256 { 0xAB70FE17C79AC6CA, -1060, -300 },
16257 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
16258 { 0xBE5691EF416BD60C, -1007, -284 },
16259 { 0x8DD01FAD907FFC3C, -980, -276 },
16260 { 0xD3515C2831559A83, -954, -268 },
16261 { 0x9D71AC8FADA6C9B5, -927, -260 },
16262 { 0xEA9C227723EE8BCB, -901, -252 },
16263 { 0xAECC49914078536D, -874, -244 },
16264 { 0x823C12795DB6CE57, -847, -236 },
16265 { 0xC21094364DFB5637, -821, -228 },
16266 { 0x9096EA6F3848984F, -794, -220 },
16267 { 0xD77485CB25823AC7, -768, -212 },
16268 { 0xA086CFCD97BF97F4, -741, -204 },
16269 { 0xEF340A98172AACE5, -715, -196 },
16270 { 0xB23867FB2A35B28E, -688, -188 },
16271 { 0x84C8D4DFD2C63F3B, -661, -180 },
16272 { 0xC5DD44271AD3CDBA, -635, -172 },
16273 { 0x936B9FCEBB25C996, -608, -164 },
16274 { 0xDBAC6C247D62A584, -582, -156 },
16275 { 0xA3AB66580D5FDAF6, -555, -148 },
16276 { 0xF3E2F893DEC3F126, -529, -140 },
16277 { 0xB5B5ADA8AAFF80B8, -502, -132 },
16278 { 0x87625F056C7C4A8B, -475, -124 },
16279 { 0xC9BCFF6034C13053, -449, -116 },
16280 { 0x964E858C91BA2655, -422, -108 },
16281 { 0xDFF9772470297EBD, -396, -100 },
16282 { 0xA6DFBD9FB8E5B88F, -369, -92 },
16283 { 0xF8A95FCF88747D94, -343, -84 },
16284 { 0xB94470938FA89BCF, -316, -76 },
16285 { 0x8A08F0F8BF0F156B, -289, -68 },
16286 { 0xCDB02555653131B6, -263, -60 },
16287 { 0x993FE2C6D07B7FAC, -236, -52 },
16288 { 0xE45C10C42A2B3B06, -210, -44 },
16289 { 0xAA242499697392D3, -183, -36 },
16290 { 0xFD87B5F28300CA0E, -157, -28 },
16291 { 0xBCE5086492111AEB, -130, -20 },
16292 { 0x8CBCCC096F5088CC, -103, -12 },
16293 { 0xD1B71758E219652C, -77, -4 },
16294 { 0x9C40000000000000, -50, 4 },
16295 { 0xE8D4A51000000000, -24, 12 },
16296 { 0xAD78EBC5AC620000, 3, 20 },
16297 { 0x813F3978F8940984, 30, 28 },
16298 { 0xC097CE7BC90715B3, 56, 36 },
16299 { 0x8F7E32CE7BEA5C70, 83, 44 },
16300 { 0xD5D238A4ABE98068, 109, 52 },
16301 { 0x9F4F2726179A2245, 136, 60 },
16302 { 0xED63A231D4C4FB27, 162, 68 },
16303 { 0xB0DE65388CC8ADA8, 189, 76 },
16304 { 0x83C7088E1AAB65DB, 216, 84 },
16305 { 0xC45D1DF942711D9A, 242, 92 },
16306 { 0x924D692CA61BE758, 269, 100 },
16307 { 0xDA01EE641A708DEA, 295, 108 },
16308 { 0xA26DA3999AEF774A, 322, 116 },
16309 { 0xF209787BB47D6B85, 348, 124 },
16310 { 0xB454E4A179DD1877, 375, 132 },
16311 { 0x865B86925B9BC5C2, 402, 140 },
16312 { 0xC83553C5C8965D3D, 428, 148 },
16313 { 0x952AB45CFA97A0B3, 455, 156 },
16314 { 0xDE469FBD99A05FE3, 481, 164 },
16315 { 0xA59BC234DB398C25, 508, 172 },
16316 { 0xF6C69A72A3989F5C, 534, 180 },
16317 { 0xB7DCBF5354E9BECE, 561, 188 },
16318 { 0x88FCF317F22241E2, 588, 196 },
16319 { 0xCC20CE9BD35C78A5, 614, 204 },
16320 { 0x98165AF37B2153DF, 641, 212 },
16321 { 0xE2A0B5DC971F303A, 667, 220 },
16322 { 0xA8D9D1535CE3B396, 694, 228 },
16323 { 0xFB9B7CD9A4A7443C, 720, 236 },
16324 { 0xBB764C4CA7A44410, 747, 244 },
16325 { 0x8BAB8EEFB6409C1A, 774, 252 },
16326 { 0xD01FEF10A657842C, 800, 260 },
16327 { 0x9B10A4E5E9913129, 827, 268 },
16328 { 0xE7109BFBA19C0C9D, 853, 276 },
16329 { 0xAC2820D9623BF429, 880, 284 },
16330 { 0x80444B5E7AA7CF85, 907, 292 },
16331 { 0xBF21E44003ACDD2D, 933, 300 },
16332 { 0x8E679C2F5E44FF8F, 960, 308 },
16333 { 0xD433179D9C8CB841, 986, 316 },
16334 { 0x9E19DB92B4E31BA9, 1013, 324 },
16335 }
16336 };
16337
16338 // This computation gives exactly the same results for k as
16339 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
16340 // for |e| <= 1500, but doesn't require floating-point operations.
16341 // NB: log_10(2) ~= 78913 / 2^18
16342 JSON_ASSERT(e >= -1500);
16343 JSON_ASSERT(e <= 1500);
16344 const int f = kAlpha - e - 1;
16345 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
16346
16347 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
16348 JSON_ASSERT(index >= 0);
16349 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
16350
16351 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
16352 JSON_ASSERT(kAlpha <= cached.e + e + 64);
16353 JSON_ASSERT(kGamma >= cached.e + e + 64);
16354
16355 return cached;
16356}
16357
16362inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
16363{
16364 // LCOV_EXCL_START
16365 if (n >= 1000000000)
16366 {
16367 pow10 = 1000000000;
16368 return 10;
16369 }
16370 // LCOV_EXCL_STOP
16371 if (n >= 100000000)
16372 {
16373 pow10 = 100000000;
16374 return 9;
16375 }
16376 if (n >= 10000000)
16377 {
16378 pow10 = 10000000;
16379 return 8;
16380 }
16381 if (n >= 1000000)
16382 {
16383 pow10 = 1000000;
16384 return 7;
16385 }
16386 if (n >= 100000)
16387 {
16388 pow10 = 100000;
16389 return 6;
16390 }
16391 if (n >= 10000)
16392 {
16393 pow10 = 10000;
16394 return 5;
16395 }
16396 if (n >= 1000)
16397 {
16398 pow10 = 1000;
16399 return 4;
16400 }
16401 if (n >= 100)
16402 {
16403 pow10 = 100;
16404 return 3;
16405 }
16406 if (n >= 10)
16407 {
16408 pow10 = 10;
16409 return 2;
16410 }
16411
16412 pow10 = 1;
16413 return 1;
16414}
16415
16416inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
16417 std::uint64_t rest, std::uint64_t ten_k)
16418{
16419 JSON_ASSERT(len >= 1);
16420 JSON_ASSERT(dist <= delta);
16421 JSON_ASSERT(rest <= delta);
16422 JSON_ASSERT(ten_k > 0);
16423
16424 // <--------------------------- delta ---->
16425 // <---- dist --------->
16426 // --------------[------------------+-------------------]--------------
16427 // M- w M+
16428 //
16429 // ten_k
16430 // <------>
16431 // <---- rest ---->
16432 // --------------[------------------+----+--------------]--------------
16433 // w V
16434 // = buf * 10^k
16435 //
16436 // ten_k represents a unit-in-the-last-place in the decimal representation
16437 // stored in buf.
16438 // Decrement buf by ten_k while this takes buf closer to w.
16439
16440 // The tests are written in this order to avoid overflow in unsigned
16441 // integer arithmetic.
16442
16443 while (rest < dist
16444 && delta - rest >= ten_k
16445 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
16446 {
16447 JSON_ASSERT(buf[len - 1] != '0');
16448 buf[len - 1]--;
16449 rest += ten_k;
16450 }
16451}
16452
16457inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
16458 diyfp M_minus, diyfp w, diyfp M_plus)
16459{
16460 static_assert(kAlpha >= -60, "internal error");
16461 static_assert(kGamma <= -32, "internal error");
16462
16463 // Generates the digits (and the exponent) of a decimal floating-point
16464 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
16465 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
16466 //
16467 // <--------------------------- delta ---->
16468 // <---- dist --------->
16469 // --------------[------------------+-------------------]--------------
16470 // M- w M+
16471 //
16472 // Grisu2 generates the digits of M+ from left to right and stops as soon as
16473 // V is in [M-,M+].
16474
16475 JSON_ASSERT(M_plus.e >= kAlpha);
16476 JSON_ASSERT(M_plus.e <= kGamma);
16477
16478 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
16479 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
16480
16481 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
16482 //
16483 // M+ = f * 2^e
16484 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
16485 // = ((p1 ) * 2^-e + (p2 )) * 2^e
16486 // = p1 + p2 * 2^e
16487
16488 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
16489
16490 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
16491 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
16492
16493 // 1)
16494 //
16495 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
16496
16497 JSON_ASSERT(p1 > 0);
16498
16499 std::uint32_t pow10{};
16500 const int k = find_largest_pow10(p1, pow10);
16501
16502 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
16503 //
16504 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
16505 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
16506 //
16507 // M+ = p1 + p2 * 2^e
16508 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
16509 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
16510 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
16511 //
16512 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
16513 //
16514 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
16515 //
16516 // but stop as soon as
16517 //
16518 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
16519
16520 int n = k;
16521 while (n > 0)
16522 {
16523 // Invariants:
16524 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
16525 // pow10 = 10^(n-1) <= p1 < 10^n
16526 //
16527 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
16528 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
16529 //
16530 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
16531 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
16532 //
16533 JSON_ASSERT(d <= 9);
16534 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16535 //
16536 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
16537 //
16538 p1 = r;
16539 n--;
16540 //
16541 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
16542 // pow10 = 10^n
16543 //
16544
16545 // Now check if enough digits have been generated.
16546 // Compute
16547 //
16548 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
16549 //
16550 // Note:
16551 // Since rest and delta share the same exponent e, it suffices to
16552 // compare the significands.
16553 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
16554 if (rest <= delta)
16555 {
16556 // V = buffer * 10^n, with M- <= V <= M+.
16557
16558 decimal_exponent += n;
16559
16560 // We may now just stop. But instead look if the buffer could be
16561 // decremented to bring V closer to w.
16562 //
16563 // pow10 = 10^n is now 1 ulp in the decimal representation V.
16564 // The rounding procedure works with diyfp's with an implicit
16565 // exponent of e.
16566 //
16567 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16568 //
16569 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16570 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16571
16572 return;
16573 }
16574
16575 pow10 /= 10;
16576 //
16577 // pow10 = 10^(n-1) <= p1 < 10^n
16578 // Invariants restored.
16579 }
16580
16581 // 2)
16582 //
16583 // The digits of the integral part have been generated:
16584 //
16585 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16586 // = buffer + p2 * 2^e
16587 //
16588 // Now generate the digits of the fractional part p2 * 2^e.
16589 //
16590 // Note:
16591 // No decimal point is generated: the exponent is adjusted instead.
16592 //
16593 // p2 actually represents the fraction
16594 //
16595 // p2 * 2^e
16596 // = p2 / 2^-e
16597 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16598 //
16599 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16600 //
16601 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16602 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16603 //
16604 // using
16605 //
16606 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16607 // = ( d) * 2^-e + ( r)
16608 //
16609 // or
16610 // 10^m * p2 * 2^e = d + r * 2^e
16611 //
16612 // i.e.
16613 //
16614 // M+ = buffer + p2 * 2^e
16615 // = buffer + 10^-m * (d + r * 2^e)
16616 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16617 //
16618 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16619
16620 JSON_ASSERT(p2 > delta);
16621
16622 int m = 0;
16623 for (;;)
16624 {
16625 // Invariant:
16626 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16627 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16628 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16629 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16630 //
16631 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16632 p2 *= 10;
16633 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16634 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16635 //
16636 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16637 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16638 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16639 //
16640 JSON_ASSERT(d <= 9);
16641 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16642 //
16643 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16644 //
16645 p2 = r;
16646 m++;
16647 //
16648 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16649 // Invariant restored.
16650
16651 // Check if enough digits have been generated.
16652 //
16653 // 10^-m * p2 * 2^e <= delta * 2^e
16654 // p2 * 2^e <= 10^m * delta * 2^e
16655 // p2 <= 10^m * delta
16656 delta *= 10;
16657 dist *= 10;
16658 if (p2 <= delta)
16659 {
16660 break;
16661 }
16662 }
16663
16664 // V = buffer * 10^-m, with M- <= V <= M+.
16665
16666 decimal_exponent -= m;
16667
16668 // 1 ulp in the decimal representation is now 10^-m.
16669 // Since delta and dist are now scaled by 10^m, we need to do the
16670 // same with ulp in order to keep the units in sync.
16671 //
16672 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16673 //
16674 const std::uint64_t ten_m = one.f;
16675 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16676
16677 // By construction this algorithm generates the shortest possible decimal
16678 // number (Loitsch, Theorem 6.2) which rounds back to w.
16679 // For an input number of precision p, at least
16680 //
16681 // N = 1 + ceil(p * log_10(2))
16682 //
16683 // decimal digits are sufficient to identify all binary floating-point
16684 // numbers (Matula, "In-and-Out conversions").
16685 // This implies that the algorithm does not produce more than N decimal
16686 // digits.
16687 //
16688 // N = 17 for p = 53 (IEEE double precision)
16689 // N = 9 for p = 24 (IEEE single precision)
16690}
16691
16698inline void grisu2(char* buf, int& len, int& decimal_exponent,
16699 diyfp m_minus, diyfp v, diyfp m_plus)
16700{
16701 JSON_ASSERT(m_plus.e == m_minus.e);
16702 JSON_ASSERT(m_plus.e == v.e);
16703
16704 // --------(-----------------------+-----------------------)-------- (A)
16705 // m- v m+
16706 //
16707 // --------------------(-----------+-----------------------)-------- (B)
16708 // m- v m+
16709 //
16710 // First scale v (and m- and m+) such that the exponent is in the range
16711 // [alpha, gamma].
16712
16713 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16714
16715 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16716
16717 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16718 const diyfp w = diyfp::mul(v, c_minus_k);
16719 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16720 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16721
16722 // ----(---+---)---------------(---+---)---------------(---+---)----
16723 // w- w w+
16724 // = c*m- = c*v = c*m+
16725 //
16726 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16727 // w+ are now off by a small amount.
16728 // In fact:
16729 //
16730 // w - v * 10^k < 1 ulp
16731 //
16732 // To account for this inaccuracy, add resp. subtract 1 ulp.
16733 //
16734 // --------+---[---------------(---+---)---------------]---+--------
16735 // w- M- w M+ w+
16736 //
16737 // Now any number in [M-, M+] (bounds included) will round to w when input,
16738 // regardless of how the input rounding algorithm breaks ties.
16739 //
16740 // And digit_gen generates the shortest possible such number in [M-, M+].
16741 // Note that this does not mean that Grisu2 always generates the shortest
16742 // possible number in the interval (m-, m+).
16743 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16744 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16745
16746 decimal_exponent = -cached.k; // = -(-k) = k
16747
16748 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16749}
16750
16756template<typename FloatType>
16758void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16759{
16760 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16761 "internal error: not enough precision");
16762
16763 JSON_ASSERT(std::isfinite(value));
16764 JSON_ASSERT(value > 0);
16765
16766 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16767 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16768 // decimal representations are not exactly "short".
16769 //
16770 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16771 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16772 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
16773 // does.
16774 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16775 // representation using the corresponding std::from_chars function recovers value exactly". That
16776 // indicates that single precision floating-point numbers should be recovered using
16777 // 'std::strtof'.
16778 //
16779 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16780 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16781 // value is off by 1 ulp.
16782#if 0
16783 const boundaries w = compute_boundaries(static_cast<double>(value));
16784#else
16786#endif
16787
16788 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16789}
16790
16798inline char* append_exponent(char* buf, int e)
16799{
16800 JSON_ASSERT(e > -1000);
16801 JSON_ASSERT(e < 1000);
16802
16803 if (e < 0)
16804 {
16805 e = -e;
16806 *buf++ = '-';
16807 }
16808 else
16809 {
16810 *buf++ = '+';
16811 }
16812
16813 auto k = static_cast<std::uint32_t>(e);
16814 if (k < 10)
16815 {
16816 // Always print at least two digits in the exponent.
16817 // This is for compatibility with printf("%g").
16818 *buf++ = '0';
16819 *buf++ = static_cast<char>('0' + k);
16820 }
16821 else if (k < 100)
16822 {
16823 *buf++ = static_cast<char>('0' + k / 10);
16824 k %= 10;
16825 *buf++ = static_cast<char>('0' + k);
16826 }
16827 else
16828 {
16829 *buf++ = static_cast<char>('0' + k / 100);
16830 k %= 100;
16831 *buf++ = static_cast<char>('0' + k / 10);
16832 k %= 10;
16833 *buf++ = static_cast<char>('0' + k);
16834 }
16835
16836 return buf;
16837}
16838
16850inline char* format_buffer(char* buf, int len, int decimal_exponent,
16851 int min_exp, int max_exp)
16852{
16853 JSON_ASSERT(min_exp < 0);
16854 JSON_ASSERT(max_exp > 0);
16855
16856 const int k = len;
16857 const int n = len + decimal_exponent;
16858
16859 // v = buf * 10^(n-k)
16860 // k is the length of the buffer (number of decimal digits)
16861 // n is the position of the decimal point relative to the start of the buffer.
16862
16863 if (k <= n && n <= max_exp)
16864 {
16865 // digits[000]
16866 // len <= max_exp + 2
16867
16868 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16869 // Make it look like a floating-point number (#362, #378)
16870 buf[n + 0] = '.';
16871 buf[n + 1] = '0';
16872 return buf + (static_cast<size_t>(n) + 2);
16873 }
16874
16875 if (0 < n && n <= max_exp)
16876 {
16877 // dig.its
16878 // len <= max_digits10 + 1
16879
16880 JSON_ASSERT(k > n);
16881
16882 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16883 buf[n] = '.';
16884 return buf + (static_cast<size_t>(k) + 1U);
16885 }
16886
16887 if (min_exp < n && n <= 0)
16888 {
16889 // 0.[000]digits
16890 // len <= 2 + (-min_exp - 1) + max_digits10
16891
16892 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16893 buf[0] = '0';
16894 buf[1] = '.';
16895 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16896 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16897 }
16898
16899 if (k == 1)
16900 {
16901 // dE+123
16902 // len <= 1 + 5
16903
16904 buf += 1;
16905 }
16906 else
16907 {
16908 // d.igitsE+123
16909 // len <= max_digits10 + 1 + 5
16910
16911 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16912 buf[1] = '.';
16913 buf += 1 + static_cast<size_t>(k);
16914 }
16915
16916 *buf++ = 'e';
16917 return append_exponent(buf, n - 1);
16918}
16919
16920} // namespace dtoa_impl
16921
16932template<typename FloatType>
16935char* to_chars(char* first, const char* last, FloatType value)
16936{
16937 static_cast<void>(last); // maybe unused - fix warning
16938 JSON_ASSERT(std::isfinite(value));
16939
16940 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16941 if (std::signbit(value))
16942 {
16943 value = -value;
16944 *first++ = '-';
16945 }
16946
16947#ifdef __GNUC__
16948#pragma GCC diagnostic push
16949#pragma GCC diagnostic ignored "-Wfloat-equal"
16950#endif
16951 if (value == 0) // +-0
16952 {
16953 *first++ = '0';
16954 // Make it look like a floating-point number (#362, #378)
16955 *first++ = '.';
16956 *first++ = '0';
16957 return first;
16958 }
16959#ifdef __GNUC__
16960#pragma GCC diagnostic pop
16961#endif
16962
16963 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16964
16965 // Compute v = buffer * 10^decimal_exponent.
16966 // The decimal digits are stored in the buffer, which needs to be interpreted
16967 // as an unsigned decimal integer.
16968 // len is the length of the buffer, i.e. the number of decimal digits.
16969 int len = 0;
16970 int decimal_exponent = 0;
16971 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16972
16973 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16974
16975 // Format the buffer like printf("%.*g", prec, value)
16976 constexpr int kMinExp = -4;
16977 // Use digits10 here to increase compatibility with version 2.
16978 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16979
16980 JSON_ASSERT(last - first >= kMaxExp + 2);
16981 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16982 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16983
16984 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16985}
16986
16987} // namespace detail
16988} // namespace nlohmann
16989
16990// #include <nlohmann/detail/exceptions.hpp>
16991
16992// #include <nlohmann/detail/macro_scope.hpp>
16993
16994// #include <nlohmann/detail/meta/cpp_future.hpp>
16995
16996// #include <nlohmann/detail/output/binary_writer.hpp>
16997
16998// #include <nlohmann/detail/output/output_adapters.hpp>
16999
17000// #include <nlohmann/detail/string_concat.hpp>
17001
17002// #include <nlohmann/detail/value_t.hpp>
17003
17004
17005namespace nlohmann
17006{
17007namespace detail
17008{
17010// serialization //
17012
17015{
17016 strict,
17017 replace,
17018 ignore
17019};
17020
17021template<typename BasicJsonType>
17023{
17024 using string_t = typename BasicJsonType::string_t;
17025 using number_float_t = typename BasicJsonType::number_float_t;
17026 using number_integer_t = typename BasicJsonType::number_integer_t;
17027 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17028 using binary_char_t = typename BasicJsonType::binary_t::value_type;
17029 static constexpr std::uint8_t UTF8_ACCEPT = 0;
17030 static constexpr std::uint8_t UTF8_REJECT = 1;
17031
17032 public:
17040 : o(std::move(s))
17041 , loc(std::localeconv())
17042 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17043 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17044 , indent_char(ichar)
17046 , error_handler(error_handler_)
17047 {}
17048
17049 // delete because of pointer members
17050 serializer(const serializer&) = delete;
17054 ~serializer() = default;
17055
17078 void dump(const BasicJsonType& val,
17079 const bool pretty_print,
17080 const bool ensure_ascii,
17081 const unsigned int indent_step,
17082 const unsigned int current_indent = 0)
17083 {
17084 switch (val.m_type)
17085 {
17086 case value_t::object:
17087 {
17088 if (val.m_value.object->empty())
17089 {
17090 o->write_characters("{}", 2);
17091 return;
17092 }
17093
17094 if (pretty_print)
17095 {
17096 o->write_characters("{\n", 2);
17097
17098 // variable to hold indentation for recursive calls
17099 const auto new_indent = current_indent + indent_step;
17100 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17101 {
17102 indent_string.resize(indent_string.size() * 2, ' ');
17103 }
17104
17105 // first n-1 elements
17106 auto i = val.m_value.object->cbegin();
17107 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17108 {
17109 o->write_characters(indent_string.c_str(), new_indent);
17110 o->write_character('\"');
17111 dump_escaped(i->first, ensure_ascii);
17112 o->write_characters("\": ", 3);
17113 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17114 o->write_characters(",\n", 2);
17115 }
17116
17117 // last element
17118 JSON_ASSERT(i != val.m_value.object->cend());
17119 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17120 o->write_characters(indent_string.c_str(), new_indent);
17121 o->write_character('\"');
17122 dump_escaped(i->first, ensure_ascii);
17123 o->write_characters("\": ", 3);
17124 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17125
17126 o->write_character('\n');
17127 o->write_characters(indent_string.c_str(), current_indent);
17128 o->write_character('}');
17129 }
17130 else
17131 {
17132 o->write_character('{');
17133
17134 // first n-1 elements
17135 auto i = val.m_value.object->cbegin();
17136 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17137 {
17138 o->write_character('\"');
17139 dump_escaped(i->first, ensure_ascii);
17140 o->write_characters("\":", 2);
17141 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17142 o->write_character(',');
17143 }
17144
17145 // last element
17146 JSON_ASSERT(i != val.m_value.object->cend());
17147 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17148 o->write_character('\"');
17149 dump_escaped(i->first, ensure_ascii);
17150 o->write_characters("\":", 2);
17151 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17152
17153 o->write_character('}');
17154 }
17155
17156 return;
17157 }
17158
17159 case value_t::array:
17160 {
17161 if (val.m_value.array->empty())
17162 {
17163 o->write_characters("[]", 2);
17164 return;
17165 }
17166
17167 if (pretty_print)
17168 {
17169 o->write_characters("[\n", 2);
17170
17171 // variable to hold indentation for recursive calls
17172 const auto new_indent = current_indent + indent_step;
17173 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17174 {
17175 indent_string.resize(indent_string.size() * 2, ' ');
17176 }
17177
17178 // first n-1 elements
17179 for (auto i = val.m_value.array->cbegin();
17180 i != val.m_value.array->cend() - 1; ++i)
17181 {
17182 o->write_characters(indent_string.c_str(), new_indent);
17183 dump(*i, true, ensure_ascii, indent_step, new_indent);
17184 o->write_characters(",\n", 2);
17185 }
17186
17187 // last element
17188 JSON_ASSERT(!val.m_value.array->empty());
17189 o->write_characters(indent_string.c_str(), new_indent);
17190 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
17191
17192 o->write_character('\n');
17193 o->write_characters(indent_string.c_str(), current_indent);
17194 o->write_character(']');
17195 }
17196 else
17197 {
17198 o->write_character('[');
17199
17200 // first n-1 elements
17201 for (auto i = val.m_value.array->cbegin();
17202 i != val.m_value.array->cend() - 1; ++i)
17203 {
17204 dump(*i, false, ensure_ascii, indent_step, current_indent);
17205 o->write_character(',');
17206 }
17207
17208 // last element
17209 JSON_ASSERT(!val.m_value.array->empty());
17210 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
17211
17212 o->write_character(']');
17213 }
17214
17215 return;
17216 }
17217
17218 case value_t::string:
17219 {
17220 o->write_character('\"');
17221 dump_escaped(*val.m_value.string, ensure_ascii);
17222 o->write_character('\"');
17223 return;
17224 }
17225
17226 case value_t::binary:
17227 {
17228 if (pretty_print)
17229 {
17230 o->write_characters("{\n", 2);
17231
17232 // variable to hold indentation for recursive calls
17233 const auto new_indent = current_indent + indent_step;
17234 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17235 {
17236 indent_string.resize(indent_string.size() * 2, ' ');
17237 }
17238
17239 o->write_characters(indent_string.c_str(), new_indent);
17240
17241 o->write_characters("\"bytes\": [", 10);
17242
17243 if (!val.m_value.binary->empty())
17244 {
17245 for (auto i = val.m_value.binary->cbegin();
17246 i != val.m_value.binary->cend() - 1; ++i)
17247 {
17248 dump_integer(*i);
17249 o->write_characters(", ", 2);
17250 }
17251 dump_integer(val.m_value.binary->back());
17252 }
17253
17254 o->write_characters("],\n", 3);
17255 o->write_characters(indent_string.c_str(), new_indent);
17256
17257 o->write_characters("\"subtype\": ", 11);
17258 if (val.m_value.binary->has_subtype())
17259 {
17260 dump_integer(val.m_value.binary->subtype());
17261 }
17262 else
17263 {
17264 o->write_characters("null", 4);
17265 }
17266 o->write_character('\n');
17267 o->write_characters(indent_string.c_str(), current_indent);
17268 o->write_character('}');
17269 }
17270 else
17271 {
17272 o->write_characters("{\"bytes\":[", 10);
17273
17274 if (!val.m_value.binary->empty())
17275 {
17276 for (auto i = val.m_value.binary->cbegin();
17277 i != val.m_value.binary->cend() - 1; ++i)
17278 {
17279 dump_integer(*i);
17280 o->write_character(',');
17281 }
17282 dump_integer(val.m_value.binary->back());
17283 }
17284
17285 o->write_characters("],\"subtype\":", 12);
17286 if (val.m_value.binary->has_subtype())
17287 {
17288 dump_integer(val.m_value.binary->subtype());
17289 o->write_character('}');
17290 }
17291 else
17292 {
17293 o->write_characters("null}", 5);
17294 }
17295 }
17296 return;
17297 }
17298
17299 case value_t::boolean:
17300 {
17301 if (val.m_value.boolean)
17302 {
17303 o->write_characters("true", 4);
17304 }
17305 else
17306 {
17307 o->write_characters("false", 5);
17308 }
17309 return;
17310 }
17311
17313 {
17314 dump_integer(val.m_value.number_integer);
17315 return;
17316 }
17317
17319 {
17320 dump_integer(val.m_value.number_unsigned);
17321 return;
17322 }
17323
17325 {
17326 dump_float(val.m_value.number_float);
17327 return;
17328 }
17329
17330 case value_t::discarded:
17331 {
17332 o->write_characters("<discarded>", 11);
17333 return;
17334 }
17335
17336 case value_t::null:
17337 {
17338 o->write_characters("null", 4);
17339 return;
17340 }
17341
17342 default: // LCOV_EXCL_LINE
17343 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17344 }
17345 }
17346
17362 void dump_escaped(const string_t& s, const bool ensure_ascii)
17363 {
17364 std::uint32_t codepoint{};
17365 std::uint8_t state = UTF8_ACCEPT;
17366 std::size_t bytes = 0; // number of bytes written to string_buffer
17367
17368 // number of bytes written at the point of the last valid byte
17370 std::size_t undumped_chars = 0;
17371
17372 for (std::size_t i = 0; i < s.size(); ++i)
17373 {
17374 const auto byte = static_cast<std::uint8_t>(s[i]);
17375
17376 switch (decode(state, codepoint, byte))
17377 {
17378 case UTF8_ACCEPT: // decode found a new code point
17379 {
17380 switch (codepoint)
17381 {
17382 case 0x08: // backspace
17383 {
17384 string_buffer[bytes++] = '\\';
17385 string_buffer[bytes++] = 'b';
17386 break;
17387 }
17388
17389 case 0x09: // horizontal tab
17390 {
17391 string_buffer[bytes++] = '\\';
17392 string_buffer[bytes++] = 't';
17393 break;
17394 }
17395
17396 case 0x0A: // newline
17397 {
17398 string_buffer[bytes++] = '\\';
17399 string_buffer[bytes++] = 'n';
17400 break;
17401 }
17402
17403 case 0x0C: // formfeed
17404 {
17405 string_buffer[bytes++] = '\\';
17406 string_buffer[bytes++] = 'f';
17407 break;
17408 }
17409
17410 case 0x0D: // carriage return
17411 {
17412 string_buffer[bytes++] = '\\';
17413 string_buffer[bytes++] = 'r';
17414 break;
17415 }
17416
17417 case 0x22: // quotation mark
17418 {
17419 string_buffer[bytes++] = '\\';
17420 string_buffer[bytes++] = '\"';
17421 break;
17422 }
17423
17424 case 0x5C: // reverse solidus
17425 {
17426 string_buffer[bytes++] = '\\';
17427 string_buffer[bytes++] = '\\';
17428 break;
17429 }
17430
17431 default:
17432 {
17433 // escape control characters (0x00..0x1F) or, if
17434 // ensure_ascii parameter is used, non-ASCII characters
17435 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
17436 {
17437 if (codepoint <= 0xFFFF)
17438 {
17439 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17440 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
17441 static_cast<std::uint16_t>(codepoint)));
17442 bytes += 6;
17443 }
17444 else
17445 {
17446 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17447 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
17448 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
17449 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
17450 bytes += 12;
17451 }
17452 }
17453 else
17454 {
17455 // copy byte to buffer (all previous bytes
17456 // been copied have in default case above)
17457 string_buffer[bytes++] = s[i];
17458 }
17459 break;
17460 }
17461 }
17462
17463 // write buffer and reset index; there must be 13 bytes
17464 // left, as this is the maximal number of bytes to be
17465 // written ("\uxxxx\uxxxx\0") for one code point
17466 if (string_buffer.size() - bytes < 13)
17467 {
17468 o->write_characters(string_buffer.data(), bytes);
17469 bytes = 0;
17470 }
17471
17472 // remember the byte position of this accept
17474 undumped_chars = 0;
17475 break;
17476 }
17477
17478 case UTF8_REJECT: // decode found invalid UTF-8 byte
17479 {
17480 switch (error_handler)
17481 {
17483 {
17484 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
17485 }
17486
17489 {
17490 // in case we saw this character the first time, we
17491 // would like to read it again, because the byte
17492 // may be OK for itself, but just not OK for the
17493 // previous sequence
17494 if (undumped_chars > 0)
17495 {
17496 --i;
17497 }
17498
17499 // reset length buffer to the last accepted index;
17500 // thus removing/ignoring the invalid characters
17502
17504 {
17505 // add a replacement character
17506 if (ensure_ascii)
17507 {
17508 string_buffer[bytes++] = '\\';
17509 string_buffer[bytes++] = 'u';
17510 string_buffer[bytes++] = 'f';
17511 string_buffer[bytes++] = 'f';
17512 string_buffer[bytes++] = 'f';
17513 string_buffer[bytes++] = 'd';
17514 }
17515 else
17516 {
17520 }
17521
17522 // write buffer and reset index; there must be 13 bytes
17523 // left, as this is the maximal number of bytes to be
17524 // written ("\uxxxx\uxxxx\0") for one code point
17525 if (string_buffer.size() - bytes < 13)
17526 {
17527 o->write_characters(string_buffer.data(), bytes);
17528 bytes = 0;
17529 }
17530
17532 }
17533
17534 undumped_chars = 0;
17535
17536 // continue processing the string
17537 state = UTF8_ACCEPT;
17538 break;
17539 }
17540
17541 default: // LCOV_EXCL_LINE
17542 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17543 }
17544 break;
17545 }
17546
17547 default: // decode found yet incomplete multi-byte code point
17548 {
17549 if (!ensure_ascii)
17550 {
17551 // code point will not be escaped - copy byte to buffer
17552 string_buffer[bytes++] = s[i];
17553 }
17555 break;
17556 }
17557 }
17558 }
17559
17560 // we finished processing the string
17561 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17562 {
17563 // write buffer
17564 if (bytes > 0)
17565 {
17566 o->write_characters(string_buffer.data(), bytes);
17567 }
17568 }
17569 else
17570 {
17571 // we finish reading, but do not accept: string was incomplete
17572 switch (error_handler)
17573 {
17575 {
17576 JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
17577 }
17578
17580 {
17581 // write all accepted bytes
17582 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17583 break;
17584 }
17585
17587 {
17588 // write all accepted bytes
17589 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17590 // add a replacement character
17591 if (ensure_ascii)
17592 {
17593 o->write_characters("\\ufffd", 6);
17594 }
17595 else
17596 {
17597 o->write_characters("\xEF\xBF\xBD", 3);
17598 }
17599 break;
17600 }
17601
17602 default: // LCOV_EXCL_LINE
17603 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17604 }
17605 }
17606 }
17607
17608 private:
17617 inline unsigned int count_digits(number_unsigned_t x) noexcept
17618 {
17619 unsigned int n_digits = 1;
17620 for (;;)
17621 {
17622 if (x < 10)
17623 {
17624 return n_digits;
17625 }
17626 if (x < 100)
17627 {
17628 return n_digits + 1;
17629 }
17630 if (x < 1000)
17631 {
17632 return n_digits + 2;
17633 }
17634 if (x < 10000)
17635 {
17636 return n_digits + 3;
17637 }
17638 x = x / 10000u;
17639 n_digits += 4;
17640 }
17641 }
17642
17648 static std::string hex_bytes(std::uint8_t byte)
17649 {
17650 std::string result = "FF";
17651 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
17652 result[0] = nibble_to_hex[byte / 16];
17653 result[1] = nibble_to_hex[byte % 16];
17654 return result;
17655 }
17656
17657 // templates to avoid warnings about useless casts
17658 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
17659 bool is_negative_number(NumberType x)
17660 {
17661 return x < 0;
17662 }
17663
17664 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
17665 bool is_negative_number(NumberType /*unused*/)
17666 {
17667 return false;
17668 }
17669
17679 template < typename NumberType, detail::enable_if_t <
17680 std::is_integral<NumberType>::value ||
17681 std::is_same<NumberType, number_unsigned_t>::value ||
17682 std::is_same<NumberType, number_integer_t>::value ||
17683 std::is_same<NumberType, binary_char_t>::value,
17684 int > = 0 >
17685 void dump_integer(NumberType x)
17686 {
17687 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17688 {
17689 {
17690 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17691 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17692 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17693 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17694 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17695 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17696 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17697 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17698 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17699 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17700 }
17701 };
17702
17703 // special case for "0"
17704 if (x == 0)
17705 {
17706 o->write_character('0');
17707 return;
17708 }
17709
17710 // use a pointer to fill the buffer
17711 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17712
17713 number_unsigned_t abs_value;
17714
17715 unsigned int n_chars{};
17716
17717 if (is_negative_number(x))
17718 {
17719 *buffer_ptr = '-';
17720 abs_value = remove_sign(static_cast<number_integer_t>(x));
17721
17722 // account one more byte for the minus sign
17723 n_chars = 1 + count_digits(abs_value);
17724 }
17725 else
17726 {
17727 abs_value = static_cast<number_unsigned_t>(x);
17728 n_chars = count_digits(abs_value);
17729 }
17730
17731 // spare 1 byte for '\0'
17732 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17733
17734 // jump to the end to generate the string from backward,
17735 // so we later avoid reversing the result
17736 buffer_ptr += n_chars;
17737
17738 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17739 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17740 while (abs_value >= 100)
17741 {
17742 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17743 abs_value /= 100;
17744 *(--buffer_ptr) = digits_to_99[digits_index][1];
17745 *(--buffer_ptr) = digits_to_99[digits_index][0];
17746 }
17747
17748 if (abs_value >= 10)
17749 {
17750 const auto digits_index = static_cast<unsigned>(abs_value);
17751 *(--buffer_ptr) = digits_to_99[digits_index][1];
17752 *(--buffer_ptr) = digits_to_99[digits_index][0];
17753 }
17754 else
17755 {
17756 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17757 }
17758
17759 o->write_characters(number_buffer.data(), n_chars);
17760 }
17761
17770 void dump_float(number_float_t x)
17771 {
17772 // NaN / inf
17773 if (!std::isfinite(x))
17774 {
17775 o->write_characters("null", 4);
17776 return;
17777 }
17778
17779 // If number_float_t is an IEEE-754 single or double precision number,
17780 // use the Grisu2 algorithm to produce short numbers which are
17781 // guaranteed to round-trip, using strtof and strtod, resp.
17782 //
17783 // NB: The test below works if <long double> == <double>.
17784 static constexpr bool is_ieee_single_or_double
17785 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17786 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17787
17788 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17789 }
17790
17791 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17792 {
17793 auto* begin = number_buffer.data();
17794 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17795
17796 o->write_characters(begin, static_cast<size_t>(end - begin));
17797 }
17798
17799 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17800 {
17801 // get number of digits for a float -> text -> float round-trip
17802 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17803
17804 // the actual conversion
17805 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17806 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17807
17808 // negative value indicates an error
17809 JSON_ASSERT(len > 0);
17810 // check if buffer was large enough
17811 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17812
17813 // erase thousands separator
17814 if (thousands_sep != '\0')
17815 {
17816 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17817 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17818 std::fill(end, number_buffer.end(), '\0');
17819 JSON_ASSERT((end - number_buffer.begin()) <= len);
17820 len = (end - number_buffer.begin());
17821 }
17822
17823 // convert decimal point to '.'
17824 if (decimal_point != '\0' && decimal_point != '.')
17825 {
17826 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17827 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17828 if (dec_pos != number_buffer.end())
17829 {
17830 *dec_pos = '.';
17831 }
17832 }
17833
17834 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17835
17836 // determine if we need to append ".0"
17837 const bool value_is_int_like =
17838 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17839 [](char c)
17840 {
17841 return c == '.' || c == 'e';
17842 });
17843
17844 if (value_is_int_like)
17845 {
17846 o->write_characters(".0", 2);
17847 }
17848 }
17849
17871 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17872 {
17873 static const std::array<std::uint8_t, 400> utf8d =
17874 {
17875 {
17876 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
17877 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
17878 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
17879 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
17880 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
17881 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
17882 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
17883 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17884 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17885 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17886 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
17887 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
17888 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
17889 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
17890 }
17891 };
17892
17893 JSON_ASSERT(byte < utf8d.size());
17894 const std::uint8_t type = utf8d[byte];
17895
17896 codep = (state != UTF8_ACCEPT)
17897 ? (byte & 0x3fu) | (codep << 6u)
17898 : (0xFFu >> type) & (byte);
17899
17900 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17901 JSON_ASSERT(index < 400);
17902 state = utf8d[index];
17903 return state;
17904 }
17905
17906 /*
17907 * Overload to make the compiler happy while it is instantiating
17908 * dump_integer for number_unsigned_t.
17909 * Must never be called.
17910 */
17911 number_unsigned_t remove_sign(number_unsigned_t x)
17912 {
17913 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17914 return x; // LCOV_EXCL_LINE
17915 }
17916
17917 /*
17918 * Helper function for dump_integer
17919 *
17920 * This function takes a negative signed integer and returns its absolute
17921 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17922 * not directly remove the sign of an arbitrary signed integer as the
17923 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17924 * #1708 for details.
17925 */
17926 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17927 {
17928 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17929 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17930 }
17931
17932 private:
17934 output_adapter_t<char> o = nullptr;
17935
17937 std::array<char, 64> number_buffer{{}};
17938
17940 const std::lconv* loc = nullptr;
17942 const char thousands_sep = '\0';
17944 const char decimal_point = '\0';
17945
17947 std::array<char, 512> string_buffer{{}};
17948
17950 const char indent_char;
17953
17956};
17957} // namespace detail
17958} // namespace nlohmann
17959
17960// #include <nlohmann/detail/value_t.hpp>
17961
17962// #include <nlohmann/json_fwd.hpp>
17963
17964// #include <nlohmann/ordered_map.hpp>
17965
17966
17967#include <functional> // equal_to, less
17968#include <initializer_list> // initializer_list
17969#include <iterator> // input_iterator_tag, iterator_traits
17970#include <memory> // allocator
17971#include <stdexcept> // for out_of_range
17972#include <type_traits> // enable_if, is_convertible
17973#include <utility> // pair
17974#include <vector> // vector
17975
17976// #include <nlohmann/detail/macro_scope.hpp>
17977
17978
17979namespace nlohmann
17980{
17981
17984template <class Key, class T, class IgnoredLess = std::less<Key>,
17985 class Allocator = std::allocator<std::pair<const Key, T>>>
17986 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17987{
17988 using key_type = Key;
17989 using mapped_type = T;
17990 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17991 using iterator = typename Container::iterator;
17992 using const_iterator = typename Container::const_iterator;
17993 using size_type = typename Container::size_type;
17994 using value_type = typename Container::value_type;
17995#ifdef JSON_HAS_CPP_14
17996 using key_compare = std::equal_to<>;
17997#else
17998 using key_compare = std::equal_to<Key>;
17999#endif
18000
18001 // Explicit constructors instead of `using Container::Container`
18002 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18003 ordered_map() noexcept(noexcept(Container())) : Container{} {}
18004 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
18005 template <class It>
18006 ordered_map(It first, It last, const Allocator& alloc = Allocator())
18007 : Container{first, last, alloc} {}
18008 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
18009 : Container{init, alloc} {}
18010
18011 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18012 {
18013 for (auto it = this->begin(); it != this->end(); ++it)
18014 {
18015 if (m_compare(it->first, key))
18016 {
18017 return {it, false};
18018 }
18019 }
18020 Container::emplace_back(key, t);
18021 return {--this->end(), true};
18022 }
18023
18024 T& operator[](const Key& key)
18025 {
18026 return emplace(key, T{}).first->second;
18027 }
18028
18029 const T& operator[](const Key& key) const
18030 {
18031 return at(key);
18032 }
18033
18034 T& at(const Key& key)
18035 {
18036 for (auto it = this->begin(); it != this->end(); ++it)
18037 {
18038 if (m_compare(it->first, key))
18039 {
18040 return it->second;
18041 }
18042 }
18043
18044 JSON_THROW(std::out_of_range("key not found"));
18045 }
18046
18047 const T& at(const Key& key) const
18048 {
18049 for (auto it = this->begin(); it != this->end(); ++it)
18050 {
18051 if (m_compare(it->first, key))
18052 {
18053 return it->second;
18054 }
18055 }
18056
18057 JSON_THROW(std::out_of_range("key not found"));
18058 }
18059
18060 size_type erase(const Key& key)
18061 {
18062 for (auto it = this->begin(); it != this->end(); ++it)
18063 {
18064 if (m_compare(it->first, key))
18065 {
18066 // Since we cannot move const Keys, re-construct them in place
18067 for (auto next = it; ++next != this->end(); ++it)
18068 {
18069 it->~value_type(); // Destroy but keep allocation
18070 new (&*it) value_type{std::move(*next)};
18071 }
18072 Container::pop_back();
18073 return 1;
18074 }
18075 }
18076 return 0;
18077 }
18078
18080 {
18081 return erase(pos, std::next(pos));
18082 }
18083
18085 {
18086 const auto elements_affected = std::distance(first, last);
18087 const auto offset = std::distance(Container::begin(), first);
18088
18089 // This is the start situation. We need to delete elements_affected
18090 // elements (3 in this example: e, f, g), and need to return an
18091 // iterator past the last deleted element (h in this example).
18092 // Note that offset is the distance from the start of the vector
18093 // to first. We will need this later.
18094
18095 // [ a, b, c, d, e, f, g, h, i, j ]
18096 // ^ ^
18097 // first last
18098
18099 // Since we cannot move const Keys, we re-construct them in place.
18100 // We start at first and re-construct (viz. copy) the elements from
18101 // the back of the vector. Example for first iteration:
18102
18103 // ,--------.
18104 // v | destroy e and re-construct with h
18105 // [ a, b, c, d, e, f, g, h, i, j ]
18106 // ^ ^
18107 // it it + elements_affected
18108
18109 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
18110 {
18111 it->~value_type(); // destroy but keep allocation
18112 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
18113 }
18114
18115 // [ a, b, c, d, h, i, j, h, i, j ]
18116 // ^ ^
18117 // first last
18118
18119 // remove the unneeded elements at the end of the vector
18120 Container::resize(this->size() - static_cast<size_type>(elements_affected));
18121
18122 // [ a, b, c, d, h, i, j ]
18123 // ^ ^
18124 // first last
18125
18126 // first is now pointing past the last deleted element, but we cannot
18127 // use this iterator, because it may have been invalidated by the
18128 // resize call. Instead, we can return begin() + offset.
18129 return Container::begin() + offset;
18130 }
18131
18132 size_type count(const Key& key) const
18133 {
18134 for (auto it = this->begin(); it != this->end(); ++it)
18135 {
18136 if (m_compare(it->first, key))
18137 {
18138 return 1;
18139 }
18140 }
18141 return 0;
18142 }
18143
18144 iterator find(const Key& key)
18145 {
18146 for (auto it = this->begin(); it != this->end(); ++it)
18147 {
18148 if (m_compare(it->first, key))
18149 {
18150 return it;
18151 }
18152 }
18153 return Container::end();
18154 }
18155
18156 const_iterator find(const Key& key) const
18157 {
18158 for (auto it = this->begin(); it != this->end(); ++it)
18159 {
18160 if (m_compare(it->first, key))
18161 {
18162 return it;
18163 }
18164 }
18165 return Container::end();
18166 }
18167
18168 std::pair<iterator, bool> insert( value_type&& value )
18169 {
18170 return emplace(value.first, std::move(value.second));
18171 }
18172
18173 std::pair<iterator, bool> insert( const value_type& value )
18174 {
18175 for (auto it = this->begin(); it != this->end(); ++it)
18176 {
18177 if (m_compare(it->first, value.first))
18178 {
18179 return {it, false};
18180 }
18181 }
18182 Container::push_back(value);
18183 return {--this->end(), true};
18184 }
18185
18186 template<typename InputIt>
18187 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
18188 std::input_iterator_tag>::value>::type;
18189
18190 template<typename InputIt, typename = require_input_iter<InputIt>>
18191 void insert(InputIt first, InputIt last)
18192 {
18193 for (auto it = first; it != last; ++it)
18194 {
18195 insert(*it);
18196 }
18197 }
18198
18199private:
18201};
18202
18203} // namespace nlohmann
18204
18205
18206#if defined(JSON_HAS_CPP_17)
18207 #include <any>
18208 #include <string_view>
18209#endif
18210
18216namespace nlohmann
18217{
18218
18238class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
18239{
18240 private:
18241 template<detail::value_t> friend struct detail::external_constructor;
18242
18243 template<typename>
18244 friend class ::nlohmann::json_pointer;
18245 // can be restored when json_pointer backwards compatibility is removed
18246 // friend ::nlohmann::json_pointer<StringType>;
18247
18248 template<typename BasicJsonType, typename InputType>
18249 friend class ::nlohmann::detail::parser;
18250 friend ::nlohmann::detail::serializer<basic_json>;
18251 template<typename BasicJsonType>
18252 friend class ::nlohmann::detail::iter_impl;
18253 template<typename BasicJsonType, typename CharType>
18254 friend class ::nlohmann::detail::binary_writer;
18255 template<typename BasicJsonType, typename InputType, typename SAX>
18256 friend class ::nlohmann::detail::binary_reader;
18257 template<typename BasicJsonType>
18258 friend class ::nlohmann::detail::json_sax_dom_parser;
18259 template<typename BasicJsonType>
18260 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
18261 friend class ::nlohmann::detail::exception;
18262
18264 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
18265
18267 // convenience aliases for types residing in namespace detail;
18269
18270 template<typename InputAdapterType>
18271 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
18272 InputAdapterType adapter,
18274 const bool allow_exceptions = true,
18275 const bool ignore_comments = false
18276 )
18277 {
18278 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
18279 std::move(cb), allow_exceptions, ignore_comments);
18280 }
18281
18282 private:
18283 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
18284 template<typename BasicJsonType>
18286 template<typename BasicJsonType>
18288 template<typename Iterator>
18289 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
18290 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
18291
18292 template<typename CharType>
18294
18295 template<typename InputType>
18297 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
18298
18301
18302 public:
18306 template<typename T, typename SFINAE>
18307 using json_serializer = JSONSerializer<T, SFINAE>;
18313 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
18314
18318
18320 // exceptions //
18322
18326
18333
18335
18336
18338 // container types //
18340
18345
18348
18353
18355 using difference_type = std::ptrdiff_t;
18357 using size_type = std::size_t;
18358
18360 using allocator_type = AllocatorType<basic_json>;
18361
18363 using pointer = typename std::allocator_traits<allocator_type>::pointer;
18365 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
18366
18375
18377
18378
18382 {
18383 return allocator_type();
18384 }
18385
18390 {
18391 basic_json result;
18392
18393 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
18394 result["name"] = "JSON for Modern C++";
18395 result["url"] = "https://github.com/nlohmann/json";
18396 result["version"]["string"] =
18400 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
18401 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
18402 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
18403
18404#ifdef _WIN32
18405 result["platform"] = "win32";
18406#elif defined __linux__
18407 result["platform"] = "linux";
18408#elif defined __APPLE__
18409 result["platform"] = "apple";
18410#elif defined __unix__
18411 result["platform"] = "unix";
18412#else
18413 result["platform"] = "unknown";
18414#endif
18415
18416#if defined(__ICC) || defined(__INTEL_COMPILER)
18417 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
18418#elif defined(__clang__)
18419 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
18420#elif defined(__GNUC__) || defined(__GNUG__)
18421 result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
18422 std::to_string(__GNUC__), '.',
18423 std::to_string(__GNUC_MINOR__), '.',
18424 std::to_string(__GNUC_PATCHLEVEL__))
18425 }
18426 };
18427#elif defined(__HP_cc) || defined(__HP_aCC)
18428 result["compiler"] = "hp"
18429#elif defined(__IBMCPP__)
18430 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
18431#elif defined(_MSC_VER)
18432 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
18433#elif defined(__PGI)
18434 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
18435#elif defined(__SUNPRO_CC)
18436 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
18437#else
18438 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
18439#endif
18440
18441
18442#if defined(_MSVC_LANG)
18443 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
18444#elif defined(__cplusplus)
18445 result["compiler"]["c++"] = std::to_string(__cplusplus);
18446#else
18447 result["compiler"]["c++"] = "unknown";
18448#endif
18449 return result;
18450 }
18451
18452
18454 // JSON value data types //
18456
18461
18466#if defined(JSON_HAS_CPP_14)
18467 // use of transparent comparator avoids unnecessary repeated construction of temporaries
18468 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
18469 using default_object_comparator_t = std::less<>;
18470#else
18471 using default_object_comparator_t = std::less<StringType>;
18472#endif
18473
18476 using object_t = ObjectType<StringType,
18477 basic_json,
18479 AllocatorType<std::pair<const StringType,
18480 basic_json>>>;
18481
18484 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18485
18488 using string_t = StringType;
18489
18492 using boolean_t = BooleanType;
18493
18496 using number_integer_t = NumberIntegerType;
18497
18500 using number_unsigned_t = NumberUnsignedType;
18501
18504 using number_float_t = NumberFloatType;
18505
18509
18513
18515
18516 private:
18517
18519 template<typename T, typename... Args>
18521 static T* create(Args&& ... args)
18522 {
18523 AllocatorType<T> alloc;
18524 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18525
18526 auto deleter = [&](T * obj)
18527 {
18528 AllocatorTraits::deallocate(alloc, obj, 1);
18529 };
18530 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18531 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18532 JSON_ASSERT(obj != nullptr);
18533 return obj.release();
18534 }
18535
18537 // JSON value storage //
18539
18566 union json_value
18567 {
18571 array_t* array;
18573 string_t* string;
18575 binary_t* binary;
18577 boolean_t boolean;
18579 number_integer_t number_integer;
18581 number_unsigned_t number_unsigned;
18583 number_float_t number_float;
18584
18586 json_value() = default;
18588 json_value(boolean_t v) noexcept : boolean(v) {}
18590 json_value(number_integer_t v) noexcept : number_integer(v) {}
18592 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18594 json_value(number_float_t v) noexcept : number_float(v) {}
18596 json_value(value_t t)
18597 {
18598 switch (t)
18599 {
18600 case value_t::object:
18601 {
18602 object = create<object_t>();
18603 break;
18604 }
18605
18606 case value_t::array:
18607 {
18608 array = create<array_t>();
18609 break;
18610 }
18611
18612 case value_t::string:
18613 {
18614 string = create<string_t>("");
18615 break;
18616 }
18617
18618 case value_t::binary:
18619 {
18620 binary = create<binary_t>();
18621 break;
18622 }
18623
18624 case value_t::boolean:
18625 {
18626 boolean = static_cast<boolean_t>(false);
18627 break;
18628 }
18629
18631 {
18632 number_integer = static_cast<number_integer_t>(0);
18633 break;
18634 }
18635
18637 {
18638 number_unsigned = static_cast<number_unsigned_t>(0);
18639 break;
18640 }
18641
18643 {
18644 number_float = static_cast<number_float_t>(0.0);
18645 break;
18646 }
18647
18648 case value_t::null:
18649 {
18650 object = nullptr; // silence warning, see #821
18651 break;
18652 }
18653
18654 case value_t::discarded:
18655 default:
18656 {
18657 object = nullptr; // silence warning, see #821
18659 {
18660 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", nullptr)); // LCOV_EXCL_LINE
18661 }
18662 break;
18663 }
18664 }
18665 }
18666
18668 json_value(const string_t& value) : string(create<string_t>(value)) {}
18669
18671 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
18672
18674 json_value(const object_t& value) : object(create<object_t>(value)) {}
18675
18677 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
18678
18680 json_value(const array_t& value) : array(create<array_t>(value)) {}
18681
18683 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
18684
18686 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
18687
18689 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
18690
18692 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
18693
18695 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
18696
18697 void destroy(value_t t)
18698 {
18699 if (t == value_t::array || t == value_t::object)
18700 {
18701 // flatten the current json_value to a heap-allocated stack
18702 std::vector<basic_json> stack;
18703
18704 // move the top-level items to stack
18705 if (t == value_t::array)
18706 {
18707 stack.reserve(array->size());
18708 std::move(array->begin(), array->end(), std::back_inserter(stack));
18709 }
18710 else
18711 {
18712 stack.reserve(object->size());
18713 for (auto&& it : *object)
18714 {
18715 stack.push_back(std::move(it.second));
18716 }
18717 }
18718
18719 while (!stack.empty())
18720 {
18721 // move the last item to local variable to be processed
18722 basic_json current_item(std::move(stack.back()));
18723 stack.pop_back();
18724
18725 // if current_item is array/object, move
18726 // its children to the stack to be processed later
18727 if (current_item.is_array())
18728 {
18729 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18730
18731 current_item.m_value.array->clear();
18732 }
18733 else if (current_item.is_object())
18734 {
18735 for (auto&& it : *current_item.m_value.object)
18736 {
18737 stack.push_back(std::move(it.second));
18738 }
18739
18740 current_item.m_value.object->clear();
18741 }
18742
18743 // it's now safe that current_item get destructed
18744 // since it doesn't have any children
18745 }
18746 }
18747
18748 switch (t)
18749 {
18750 case value_t::object:
18751 {
18752 AllocatorType<object_t> alloc;
18753 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18754 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18755 break;
18756 }
18757
18758 case value_t::array:
18759 {
18760 AllocatorType<array_t> alloc;
18761 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18762 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18763 break;
18764 }
18765
18766 case value_t::string:
18767 {
18768 AllocatorType<string_t> alloc;
18769 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18770 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18771 break;
18772 }
18773
18774 case value_t::binary:
18775 {
18776 AllocatorType<binary_t> alloc;
18777 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18778 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18779 break;
18780 }
18781
18782 case value_t::null:
18783 case value_t::boolean:
18787 case value_t::discarded:
18788 default:
18789 {
18790 break;
18791 }
18792 }
18793 }
18794 };
18795
18796 private:
18815 void assert_invariant(bool check_parents = true) const noexcept
18816 {
18817 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18818 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18819 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18820 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18821
18822#if JSON_DIAGNOSTICS
18823 JSON_TRY
18824 {
18825 // cppcheck-suppress assertWithSideEffect
18826 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18827 {
18828 return j.m_parent == this;
18829 }));
18830 }
18831 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18832#endif
18833 static_cast<void>(check_parents);
18834 }
18835
18836 void set_parents()
18837 {
18838#if JSON_DIAGNOSTICS
18839 switch (m_type)
18840 {
18841 case value_t::array:
18842 {
18843 for (auto& element : *m_value.array)
18844 {
18845 element.m_parent = this;
18846 }
18847 break;
18848 }
18849
18850 case value_t::object:
18851 {
18852 for (auto& element : *m_value.object)
18853 {
18854 element.second.m_parent = this;
18855 }
18856 break;
18857 }
18858
18859 case value_t::null:
18860 case value_t::string:
18861 case value_t::boolean:
18865 case value_t::binary:
18866 case value_t::discarded:
18867 default:
18868 break;
18869 }
18870#endif
18871 }
18872
18873 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
18874 {
18875#if JSON_DIAGNOSTICS
18876 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
18877 {
18878 (it + i)->m_parent = this;
18879 }
18880#else
18881 static_cast<void>(count_set_parents);
18882#endif
18883 return it;
18884 }
18885
18886 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
18887 {
18888#if JSON_DIAGNOSTICS
18889 if (old_capacity != static_cast<std::size_t>(-1))
18890 {
18891 // see https://github.com/nlohmann/json/issues/2838
18893 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18894 {
18895 // capacity has changed: update all parents
18896 set_parents();
18897 return j;
18898 }
18899 }
18900
18901 // ordered_json uses a vector internally, so pointers could have
18902 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18903#ifdef JSON_HEDLEY_MSVC_VERSION
18904#pragma warning(push )
18905#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18906#endif
18908 {
18909 set_parents();
18910 return j;
18911 }
18912#ifdef JSON_HEDLEY_MSVC_VERSION
18913#pragma warning( pop )
18914#endif
18915
18916 j.m_parent = this;
18917#else
18918 static_cast<void>(j);
18919 static_cast<void>(old_capacity);
18920#endif
18921 return j;
18922 }
18923
18924 public:
18926 // JSON parser callback //
18928
18932
18936
18938 // constructors //
18940
18945
18949 : m_type(v), m_value(v)
18950 {
18951 assert_invariant();
18952 }
18953
18956 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
18957 : basic_json(value_t::null)
18958 {
18959 assert_invariant();
18960 }
18961
18964 template < typename CompatibleType,
18968 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18969 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18970 std::forward<CompatibleType>(val))))
18971 {
18972 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18973 set_parents();
18974 assert_invariant();
18975 }
18976
18979 template < typename BasicJsonType,
18981 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18982 basic_json(const BasicJsonType& val)
18983 {
18984 using other_boolean_t = typename BasicJsonType::boolean_t;
18985 using other_number_float_t = typename BasicJsonType::number_float_t;
18986 using other_number_integer_t = typename BasicJsonType::number_integer_t;
18987 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18988 using other_string_t = typename BasicJsonType::string_t;
18989 using other_object_t = typename BasicJsonType::object_t;
18990 using other_array_t = typename BasicJsonType::array_t;
18991 using other_binary_t = typename BasicJsonType::binary_t;
18992
18993 switch (val.type())
18994 {
18995 case value_t::boolean:
18996 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18997 break;
18999 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19000 break;
19002 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19003 break;
19005 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19006 break;
19007 case value_t::string:
19008 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19009 break;
19010 case value_t::object:
19011 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19012 break;
19013 case value_t::array:
19014 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19015 break;
19016 case value_t::binary:
19017 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19018 break;
19019 case value_t::null:
19020 *this = nullptr;
19021 break;
19022 case value_t::discarded:
19023 m_type = value_t::discarded;
19024 break;
19025 default: // LCOV_EXCL_LINE
19026 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19027 }
19028 set_parents();
19029 assert_invariant();
19030 }
19031
19035 bool type_deduction = true,
19036 value_t manual_type = value_t::array)
19037 {
19038 // check if each element is an array with two elements whose first
19039 // element is a string
19040 bool is_an_object = std::all_of(init.begin(), init.end(),
19041 [](const detail::json_ref<basic_json>& element_ref)
19042 {
19043 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19044 });
19045
19046 // adjust type if type deduction is not wanted
19047 if (!type_deduction)
19048 {
19049 // if array is wanted, do not create an object though possible
19050 if (manual_type == value_t::array)
19051 {
19052 is_an_object = false;
19053 }
19054
19055 // if object is wanted but impossible, throw an exception
19056 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19057 {
19058 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
19059 }
19060 }
19061
19062 if (is_an_object)
19063 {
19064 // the initializer list is a list of pairs -> create object
19065 m_type = value_t::object;
19067
19068 for (auto& element_ref : init)
19069 {
19070 auto element = element_ref.moved_or_copied();
19071 m_value.object->emplace(
19072 std::move(*((*element.m_value.array)[0].m_value.string)),
19073 std::move((*element.m_value.array)[1]));
19074 }
19075 }
19076 else
19077 {
19078 // the initializer list describes an array -> create array
19079 m_type = value_t::array;
19080 m_value.array = create<array_t>(init.begin(), init.end());
19081 }
19082
19083 set_parents();
19084 assert_invariant();
19085 }
19086
19090 static basic_json binary(const typename binary_t::container_type& init)
19091 {
19092 auto res = basic_json();
19093 res.m_type = value_t::binary;
19094 res.m_value = init;
19095 return res;
19096 }
19097
19101 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19102 {
19103 auto res = basic_json();
19104 res.m_type = value_t::binary;
19105 res.m_value = binary_t(init, subtype);
19106 return res;
19107 }
19108
19113 {
19114 auto res = basic_json();
19115 res.m_type = value_t::binary;
19116 res.m_value = std::move(init);
19117 return res;
19118 }
19119
19123 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19124 {
19125 auto res = basic_json();
19126 res.m_type = value_t::binary;
19127 res.m_value = binary_t(std::move(init), subtype);
19128 return res;
19129 }
19130
19135 {
19136 return basic_json(init, false, value_t::array);
19137 }
19138
19143 {
19144 return basic_json(init, false, value_t::object);
19145 }
19146
19150 : m_type(value_t::array)
19151 {
19152 m_value.array = create<array_t>(cnt, val);
19153 set_parents();
19154 assert_invariant();
19155 }
19156
19159 template < class InputIT, typename std::enable_if <
19160 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19161 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19162 basic_json(InputIT first, InputIT last)
19163 {
19164 JSON_ASSERT(first.m_object != nullptr);
19165 JSON_ASSERT(last.m_object != nullptr);
19166
19167 // make sure iterator fits the current value
19168 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19169 {
19170 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
19171 }
19172
19173 // copy type from first iterator
19174 m_type = first.m_object->m_type;
19175
19176 // check if iterator range is complete for primitive values
19177 switch (m_type)
19178 {
19179 case value_t::boolean:
19183 case value_t::string:
19184 {
19185 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19186 || !last.m_it.primitive_iterator.is_end()))
19187 {
19188 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
19189 }
19190 break;
19191 }
19192
19193 case value_t::null:
19194 case value_t::object:
19195 case value_t::array:
19196 case value_t::binary:
19197 case value_t::discarded:
19198 default:
19199 break;
19200 }
19201
19202 switch (m_type)
19203 {
19205 {
19206 m_value.number_integer = first.m_object->m_value.number_integer;
19207 break;
19208 }
19209
19211 {
19212 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19213 break;
19214 }
19215
19217 {
19218 m_value.number_float = first.m_object->m_value.number_float;
19219 break;
19220 }
19221
19222 case value_t::boolean:
19223 {
19224 m_value.boolean = first.m_object->m_value.boolean;
19225 break;
19226 }
19227
19228 case value_t::string:
19229 {
19230 m_value = *first.m_object->m_value.string;
19231 break;
19232 }
19233
19234 case value_t::object:
19235 {
19236 m_value.object = create<object_t>(first.m_it.object_iterator,
19237 last.m_it.object_iterator);
19238 break;
19239 }
19240
19241 case value_t::array:
19242 {
19243 m_value.array = create<array_t>(first.m_it.array_iterator,
19244 last.m_it.array_iterator);
19245 break;
19246 }
19247
19248 case value_t::binary:
19249 {
19250 m_value = *first.m_object->m_value.binary;
19251 break;
19252 }
19253
19254 case value_t::null:
19255 case value_t::discarded:
19256 default:
19257 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
19258 }
19259
19260 set_parents();
19261 assert_invariant();
19262 }
19263
19264
19266 // other constructors and destructor //
19268
19269 template<typename JsonRef,
19271 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19272 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19273
19277 : m_type(other.m_type)
19278 {
19279 // check of passed value is valid
19280 other.assert_invariant();
19281
19282 switch (m_type)
19283 {
19284 case value_t::object:
19285 {
19286 m_value = *other.m_value.object;
19287 break;
19288 }
19289
19290 case value_t::array:
19291 {
19292 m_value = *other.m_value.array;
19293 break;
19294 }
19295
19296 case value_t::string:
19297 {
19298 m_value = *other.m_value.string;
19299 break;
19300 }
19301
19302 case value_t::boolean:
19303 {
19304 m_value = other.m_value.boolean;
19305 break;
19306 }
19307
19309 {
19310 m_value = other.m_value.number_integer;
19311 break;
19312 }
19313
19315 {
19316 m_value = other.m_value.number_unsigned;
19317 break;
19318 }
19319
19321 {
19322 m_value = other.m_value.number_float;
19323 break;
19324 }
19325
19326 case value_t::binary:
19327 {
19328 m_value = *other.m_value.binary;
19329 break;
19330 }
19331
19332 case value_t::null:
19333 case value_t::discarded:
19334 default:
19335 break;
19336 }
19337
19338 set_parents();
19339 assert_invariant();
19340 }
19341
19344 basic_json(basic_json&& other) noexcept
19345 : m_type(std::move(other.m_type)),
19346 m_value(std::move(other.m_value))
19347 {
19348 // check that passed value is valid
19349 other.assert_invariant(false);
19350
19351 // invalidate payload
19352 other.m_type = value_t::null;
19353 other.m_value = {};
19354
19355 set_parents();
19356 assert_invariant();
19357 }
19358
19362 std::is_nothrow_move_constructible<value_t>::value&&
19363 std::is_nothrow_move_assignable<value_t>::value&&
19364 std::is_nothrow_move_constructible<json_value>::value&&
19365 std::is_nothrow_move_assignable<json_value>::value
19366 )
19367 {
19368 // check that passed value is valid
19369 other.assert_invariant();
19370
19371 using std::swap;
19372 swap(m_type, other.m_type);
19373 swap(m_value, other.m_value);
19374
19375 set_parents();
19376 assert_invariant();
19377 return *this;
19378 }
19379
19382 ~basic_json() noexcept
19383 {
19384 assert_invariant(false);
19385 m_value.destroy(m_type);
19386 }
19387
19389
19390 public:
19392 // object inspection //
19394
19398
19401 string_t dump(const int indent = -1,
19402 const char indent_char = ' ',
19403 const bool ensure_ascii = false,
19404 const error_handler_t error_handler = error_handler_t::strict) const
19405 {
19406 string_t result;
19407 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19408
19409 if (indent >= 0)
19410 {
19411 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19412 }
19413 else
19414 {
19415 s.dump(*this, false, ensure_ascii, 0);
19416 }
19417
19418 return result;
19419 }
19420
19423 constexpr value_t type() const noexcept
19424 {
19425 return m_type;
19426 }
19427
19430 constexpr bool is_primitive() const noexcept
19431 {
19432 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19433 }
19434
19437 constexpr bool is_structured() const noexcept
19438 {
19439 return is_array() || is_object();
19440 }
19441
19444 constexpr bool is_null() const noexcept
19445 {
19446 return m_type == value_t::null;
19447 }
19448
19451 constexpr bool is_boolean() const noexcept
19452 {
19453 return m_type == value_t::boolean;
19454 }
19455
19458 constexpr bool is_number() const noexcept
19459 {
19460 return is_number_integer() || is_number_float();
19461 }
19462
19465 constexpr bool is_number_integer() const noexcept
19466 {
19467 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19468 }
19469
19472 constexpr bool is_number_unsigned() const noexcept
19473 {
19474 return m_type == value_t::number_unsigned;
19475 }
19476
19479 constexpr bool is_number_float() const noexcept
19480 {
19481 return m_type == value_t::number_float;
19482 }
19483
19486 constexpr bool is_object() const noexcept
19487 {
19488 return m_type == value_t::object;
19489 }
19490
19493 constexpr bool is_array() const noexcept
19494 {
19495 return m_type == value_t::array;
19496 }
19497
19500 constexpr bool is_string() const noexcept
19501 {
19502 return m_type == value_t::string;
19503 }
19504
19507 constexpr bool is_binary() const noexcept
19508 {
19509 return m_type == value_t::binary;
19510 }
19511
19514 constexpr bool is_discarded() const noexcept
19515 {
19516 return m_type == value_t::discarded;
19517 }
19518
19521 constexpr operator value_t() const noexcept
19522 {
19523 return m_type;
19524 }
19525
19527
19528 private:
19530 // value access //
19532
19534 boolean_t get_impl(boolean_t* /*unused*/) const
19535 {
19537 {
19538 return m_value.boolean;
19539 }
19540
19541 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
19542 }
19543
19545 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19546 {
19547 return is_object() ? m_value.object : nullptr;
19548 }
19549
19551 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19552 {
19553 return is_object() ? m_value.object : nullptr;
19554 }
19555
19557 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19558 {
19559 return is_array() ? m_value.array : nullptr;
19560 }
19561
19563 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19564 {
19565 return is_array() ? m_value.array : nullptr;
19566 }
19567
19569 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19570 {
19571 return is_string() ? m_value.string : nullptr;
19572 }
19573
19575 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19576 {
19577 return is_string() ? m_value.string : nullptr;
19578 }
19579
19581 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19582 {
19583 return is_boolean() ? &m_value.boolean : nullptr;
19584 }
19585
19587 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19588 {
19589 return is_boolean() ? &m_value.boolean : nullptr;
19590 }
19591
19593 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19594 {
19595 return is_number_integer() ? &m_value.number_integer : nullptr;
19596 }
19597
19599 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19600 {
19601 return is_number_integer() ? &m_value.number_integer : nullptr;
19602 }
19603
19605 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19606 {
19607 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19608 }
19609
19611 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19612 {
19613 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19614 }
19615
19617 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19618 {
19619 return is_number_float() ? &m_value.number_float : nullptr;
19620 }
19621
19623 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19624 {
19625 return is_number_float() ? &m_value.number_float : nullptr;
19626 }
19627
19629 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19630 {
19631 return is_binary() ? m_value.binary : nullptr;
19632 }
19633
19635 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19636 {
19637 return is_binary() ? m_value.binary : nullptr;
19638 }
19639
19651 template<typename ReferenceType, typename ThisType>
19652 static ReferenceType get_ref_impl(ThisType& obj)
19653 {
19654 // delegate the call to get_ptr<>()
19655 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19656
19657 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19658 {
19659 return *ptr;
19660 }
19661
19662 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
19663 }
19664
19665 public:
19669
19672 template<typename PointerType, typename std::enable_if<
19673 std::is_pointer<PointerType>::value, int>::type = 0>
19674 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19675 {
19676 // delegate the call to get_impl_ptr<>()
19677 return get_impl_ptr(static_cast<PointerType>(nullptr));
19678 }
19679
19682 template < typename PointerType, typename std::enable_if <
19683 std::is_pointer<PointerType>::value&&
19684 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19685 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19686 {
19687 // delegate the call to get_impl_ptr<>() const
19688 return get_impl_ptr(static_cast<PointerType>(nullptr));
19689 }
19690
19691 private:
19730 template < typename ValueType,
19734 int > = 0 >
19735 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
19736 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19737 {
19738 auto ret = ValueType();
19740 return ret;
19741 }
19742
19773 template < typename ValueType,
19775 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19776 int > = 0 >
19777 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
19778 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19779 {
19781 }
19782
19798 template < typename BasicJsonType,
19800 detail::is_basic_json<BasicJsonType>::value,
19801 int > = 0 >
19802 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
19803 {
19804 return *this;
19805 }
19806
19821 template<typename BasicJsonType,
19823 std::is_same<BasicJsonType, basic_json_t>::value,
19824 int> = 0>
19825 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
19826 {
19827 return *this;
19828 }
19829
19834 template<typename PointerType,
19836 std::is_pointer<PointerType>::value,
19837 int> = 0>
19838 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
19839 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19840 {
19841 // delegate the call to get_ptr
19842 return get_ptr<PointerType>();
19843 }
19844
19845 public:
19869 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
19870#if defined(JSON_HAS_CPP_14)
19871 constexpr
19872#endif
19873 auto get() const noexcept(
19874 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
19875 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
19876 {
19877 // we cannot static_assert on ValueTypeCV being non-const, because
19878 // there is support for get<const basic_json_t>(), which is why we
19879 // still need the uncvref
19880 static_assert(!std::is_reference<ValueTypeCV>::value,
19881 "get() cannot be used with reference types, you might want to use get_ref()");
19882 return get_impl<ValueType>(detail::priority_tag<4> {});
19883 }
19884
19912 template<typename PointerType, typename std::enable_if<
19913 std::is_pointer<PointerType>::value, int>::type = 0>
19914 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19915 {
19916 // delegate the call to get_ptr
19917 return get_ptr<PointerType>();
19918 }
19919
19922 template < typename ValueType,
19926 int > = 0 >
19927 ValueType & get_to(ValueType& v) const noexcept(noexcept(
19928 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19929 {
19931 return v;
19932 }
19933
19934 // specialization to allow calling get_to with a basic_json value
19935 // see https://github.com/nlohmann/json/issues/2175
19936 template<typename ValueType,
19939 int> = 0>
19940 ValueType & get_to(ValueType& v) const
19941 {
19942 v = *this;
19943 return v;
19944 }
19945
19946 template <
19947 typename T, std::size_t N,
19948 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
19951 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
19952 noexcept(noexcept(JSONSerializer<Array>::from_json(
19953 std::declval<const basic_json_t&>(), v)))
19954 {
19956 return v;
19957 }
19958
19961 template<typename ReferenceType, typename std::enable_if<
19962 std::is_reference<ReferenceType>::value, int>::type = 0>
19963 ReferenceType get_ref()
19964 {
19965 // delegate call to get_ref_impl
19966 return get_ref_impl<ReferenceType>(*this);
19967 }
19968
19971 template < typename ReferenceType, typename std::enable_if <
19972 std::is_reference<ReferenceType>::value&&
19973 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19974 ReferenceType get_ref() const
19975 {
19976 // delegate call to get_ref_impl
19977 return get_ref_impl<ReferenceType>(*this);
19978 }
19979
20009 template < typename ValueType, typename std::enable_if <
20017
20018#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20020#endif
20021#if defined(JSON_HAS_CPP_17)
20023#endif
20025 >::value, int >::type = 0 >
20026 JSON_EXPLICIT operator ValueType() const
20027 {
20028 // delegate the call to get<>() const
20029 return get<ValueType>();
20030 }
20031
20035 {
20036 if (!is_binary())
20037 {
20038 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20039 }
20040
20041 return *get_ptr<binary_t*>();
20042 }
20043
20046 const binary_t& get_binary() const
20047 {
20048 if (!is_binary())
20049 {
20050 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20051 }
20052
20053 return *get_ptr<const binary_t*>();
20054 }
20055
20057
20058
20060 // element access //
20062
20066
20070 {
20071 // at only works for arrays
20073 {
20074 JSON_TRY
20075 {
20076 return set_parent(m_value.array->at(idx));
20077 }
20078 JSON_CATCH (std::out_of_range&)
20079 {
20080 // create better exception explanation
20081 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20082 }
20083 }
20084 else
20085 {
20086 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20087 }
20088 }
20089
20093 {
20094 // at only works for arrays
20096 {
20097 JSON_TRY
20098 {
20099 return m_value.array->at(idx);
20100 }
20101 JSON_CATCH (std::out_of_range&)
20102 {
20103 // create better exception explanation
20104 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20105 }
20106 }
20107 else
20108 {
20109 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20110 }
20111 }
20112
20115 reference at(const typename object_t::key_type& key)
20116 {
20117 // at only works for objects
20119 {
20120 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20121 }
20122
20123 auto it = m_value.object->find(key);
20124 if (it == m_value.object->end())
20125 {
20126 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20127 }
20128 return set_parent(it->second);
20129 }
20130
20133 template<class KeyType, detail::enable_if_t<
20135 reference at(KeyType && key)
20136 {
20137 // at only works for objects
20139 {
20140 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20141 }
20142
20143 auto it = m_value.object->find(std::forward<KeyType>(key));
20144 if (it == m_value.object->end())
20145 {
20146 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20147 }
20148 return set_parent(it->second);
20149 }
20150
20153 const_reference at(const typename object_t::key_type& key) const
20154 {
20155 // at only works for objects
20157 {
20158 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20159 }
20160
20161 auto it = m_value.object->find(key);
20162 if (it == m_value.object->end())
20163 {
20164 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20165 }
20166 return it->second;
20167 }
20168
20171 template<class KeyType, detail::enable_if_t<
20173 const_reference at(KeyType && key) const
20174 {
20175 // at only works for objects
20177 {
20178 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20179 }
20180
20181 auto it = m_value.object->find(std::forward<KeyType>(key));
20182 if (it == m_value.object->end())
20183 {
20184 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20185 }
20186 return it->second;
20187 }
20188
20192 {
20193 // implicitly convert null value to an empty array
20194 if (is_null())
20195 {
20196 m_type = value_t::array;
20197 m_value.array = create<array_t>();
20198 assert_invariant();
20199 }
20200
20201 // operator[] only works for arrays
20203 {
20204 // fill up array with null values if given idx is outside range
20205 if (idx >= m_value.array->size())
20206 {
20207#if JSON_DIAGNOSTICS
20208 // remember array size & capacity before resizing
20209 const auto old_size = m_value.array->size();
20210 const auto old_capacity = m_value.array->capacity();
20211#endif
20212 m_value.array->resize(idx + 1);
20213
20214#if JSON_DIAGNOSTICS
20215 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
20216 {
20217 // capacity has changed: update all parents
20218 set_parents();
20219 }
20220 else
20221 {
20222 // set parent for values added above
20223 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
20224 }
20225#endif
20226 assert_invariant();
20227 }
20228
20229 return m_value.array->operator[](idx);
20230 }
20231
20232 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20233 }
20234
20238 {
20239 // const operator[] only works for arrays
20241 {
20242 return m_value.array->operator[](idx);
20243 }
20244
20245 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20246 }
20247
20250 reference operator[](typename object_t::key_type key)
20251 {
20252 // implicitly convert null value to an empty object
20253 if (is_null())
20254 {
20255 m_type = value_t::object;
20256 m_value.object = create<object_t>();
20257 assert_invariant();
20258 }
20259
20260 // operator[] only works for objects
20262 {
20263 auto result = m_value.object->emplace(std::move(key), nullptr);
20264 return set_parent(result.first->second);
20265 }
20266
20267 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20268 }
20269
20272 const_reference operator[](const typename object_t::key_type& key) const
20273 {
20274 // const operator[] only works for objects
20276 {
20277 auto it = m_value.object->find(key);
20278 JSON_ASSERT(it != m_value.object->end());
20279 return it->second;
20280 }
20281
20282 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20283 }
20284
20285 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
20286 // (they seemingly cannot be constrained to resolve the ambiguity)
20287 template<typename T>
20289 {
20290 return operator[](typename object_t::key_type(key));
20291 }
20292
20293 template<typename T>
20295 {
20296 return operator[](typename object_t::key_type(key));
20297 }
20298
20301 template<class KeyType, detail::enable_if_t<
20303 reference operator[](KeyType && key)
20304 {
20305 // implicitly convert null value to an empty object
20306 if (is_null())
20307 {
20308 m_type = value_t::object;
20309 m_value.object = create<object_t>();
20310 assert_invariant();
20311 }
20312
20313 // operator[] only works for objects
20315 {
20316 auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
20317 return set_parent(result.first->second);
20318 }
20319
20320 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20321 }
20322
20325 template<class KeyType, detail::enable_if_t<
20327 const_reference operator[](KeyType && key) const
20328 {
20329 // const operator[] only works for objects
20331 {
20332 auto it = m_value.object->find(std::forward<KeyType>(key));
20333 JSON_ASSERT(it != m_value.object->end());
20334 return it->second;
20335 }
20336
20337 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20338 }
20339
20342 // this is the value(const typename object_t::key_type&) overload
20343 template < class KeyType, class ValueType, detail::enable_if_t <
20344 std::is_same<KeyType, typename object_t::key_type>::value
20346 && !std::is_same<value_t, ValueType>::value, int > = 0 >
20347 typename std::decay<ValueType>::type value(const KeyType& key, ValueType && default_value) const
20348 {
20349 // value only works for objects
20351 {
20352 // if key is found, return value and given default value otherwise
20353 const auto it = find(key);
20354 if (it != end())
20355 {
20356 return it->template get<typename std::decay<ValueType>::type>();
20357 }
20358
20359 return std::forward<ValueType>(default_value);
20360 }
20361
20362 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20363 }
20364
20368 string_t value(const typename object_t::key_type& key, const char* default_value) const
20369 {
20370 return value(key, string_t(default_value));
20371 }
20372
20373 // these two functions, in conjunction with value(const KeyType &, ValueType &&),
20374 // resolve an ambiguity that would otherwise occur between the json_pointer and
20375 // typename object_t::key_type & overloads
20376 template < class ValueType, detail::enable_if_t <
20378 && !std::is_same<value_t, ValueType>::value, int > = 0 >
20379 typename std::decay<ValueType>::type value(const char* key, ValueType && default_value) const
20380 {
20381 return value(typename object_t::key_type(key), std::forward<ValueType>(default_value));
20382 }
20383
20384 string_t value(const char* key, const char* default_value) const
20385 {
20386 return value(typename object_t::key_type(key), string_t(default_value));
20387 }
20388
20392 template < class KeyType, class ValueType, detail::enable_if_t <
20394 && !std::is_same<value_t, ValueType>::value
20396 typename std::decay<ValueType>::type value(KeyType && key, ValueType && default_value) const
20397 {
20398 // value only works for objects
20400 {
20401 // if key is found, return value and given default value otherwise
20402 const auto it = find(std::forward<KeyType>(key));
20403 if (it != end())
20404 {
20405 return it->template get<typename std::decay<ValueType>::type>();
20406 }
20407
20408 return std::forward<ValueType>(default_value);
20409 }
20410
20411 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20412 }
20413
20417 template < class KeyType, detail::enable_if_t <
20419 string_t value(KeyType && key, const char* default_value) const
20420 {
20421 return value(std::forward<KeyType>(key), string_t(default_value));
20422 }
20423
20426 template < class ValueType, detail::enable_if_t <
20428 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20429 {
20430 // value only works for objects
20432 {
20433 // if pointer resolves a value, return it or use default value
20434 JSON_TRY
20435 {
20436 return ptr.get_checked(this).template get<ValueType>();
20437 }
20439 {
20440 return default_value;
20441 }
20442 }
20443
20444 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20445 }
20446
20447 template < class ValueType, class BasicJsonType, detail::enable_if_t <
20450 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
20451 {
20452 return value(ptr.convert(), default_value);
20453 }
20454
20459 string_t value(const json_pointer& ptr, const char* default_value) const
20460 {
20461 return value(ptr, string_t(default_value));
20462 }
20463
20464 template<typename BasicJsonType>
20467 string_t value(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr, const char* default_value) const
20468 {
20469 return value(ptr.convert(), default_value);
20470 }
20471
20475 {
20476 return *begin();
20477 }
20478
20482 {
20483 return *cbegin();
20484 }
20485
20489 {
20490 auto tmp = end();
20491 --tmp;
20492 return *tmp;
20493 }
20494
20498 {
20499 auto tmp = cend();
20500 --tmp;
20501 return *tmp;
20502 }
20503
20506 template < class IteratorType, detail::enable_if_t <
20507 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20508 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20509 IteratorType erase(IteratorType pos)
20510 {
20511 // make sure iterator fits the current value
20512 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20513 {
20514 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
20515 }
20516
20517 IteratorType result = end();
20518
20519 switch (m_type)
20520 {
20521 case value_t::boolean:
20525 case value_t::string:
20526 case value_t::binary:
20527 {
20528 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20529 {
20530 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
20531 }
20532
20533 if (is_string())
20534 {
20535 AllocatorType<string_t> alloc;
20536 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20537 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20538 m_value.string = nullptr;
20539 }
20540 else if (is_binary())
20541 {
20542 AllocatorType<binary_t> alloc;
20543 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20544 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20545 m_value.binary = nullptr;
20546 }
20547
20548 m_type = value_t::null;
20549 assert_invariant();
20550 break;
20551 }
20552
20553 case value_t::object:
20554 {
20555 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20556 break;
20557 }
20558
20559 case value_t::array:
20560 {
20561 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20562 break;
20563 }
20564
20565 case value_t::null:
20566 case value_t::discarded:
20567 default:
20568 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20569 }
20570
20571 return result;
20572 }
20573
20576 template < class IteratorType, detail::enable_if_t <
20577 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20578 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20579 IteratorType erase(IteratorType first, IteratorType last)
20580 {
20581 // make sure iterator fits the current value
20582 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20583 {
20584 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
20585 }
20586
20587 IteratorType result = end();
20588
20589 switch (m_type)
20590 {
20591 case value_t::boolean:
20595 case value_t::string:
20596 case value_t::binary:
20597 {
20598 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20599 || !last.m_it.primitive_iterator.is_end()))
20600 {
20601 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
20602 }
20603
20604 if (is_string())
20605 {
20606 AllocatorType<string_t> alloc;
20607 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20608 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20609 m_value.string = nullptr;
20610 }
20611 else if (is_binary())
20612 {
20613 AllocatorType<binary_t> alloc;
20614 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20615 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20616 m_value.binary = nullptr;
20617 }
20618
20619 m_type = value_t::null;
20620 assert_invariant();
20621 break;
20622 }
20623
20624 case value_t::object:
20625 {
20626 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20627 last.m_it.object_iterator);
20628 break;
20629 }
20630
20631 case value_t::array:
20632 {
20633 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20634 last.m_it.array_iterator);
20635 break;
20636 }
20637
20638 case value_t::null:
20639 case value_t::discarded:
20640 default:
20641 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20642 }
20643
20644 return result;
20645 }
20646
20647 private:
20648 template < typename KeyType, detail::enable_if_t <
20650 size_type erase_internal(KeyType && key)
20651 {
20652 // this erase only works for objects
20654 {
20655 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20656 }
20657
20658 return m_value.object->erase(std::forward<KeyType>(key));
20659 }
20660
20661 template < typename KeyType, detail::enable_if_t <
20662 !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
20663 size_type erase_internal(KeyType && key)
20664 {
20665 // this erase only works for objects
20667 {
20668 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20669 }
20670
20671 const auto it = m_value.object->find(std::forward<KeyType>(key));
20672 if (it != m_value.object->end())
20673 {
20674 m_value.object->erase(it);
20675 return 1;
20676 }
20677 return 0;
20678 }
20679
20680 public:
20681
20684 size_type erase(const typename object_t::key_type& key)
20685 {
20686 // the indirection via erase_internal() is added to avoid making this
20687 // function a template and thus de-rank it during overload resolution
20688 return erase_internal(key);
20689 }
20690
20693 template<class KeyType, detail::enable_if_t<
20695 size_type erase(KeyType && key)
20696 {
20697 return erase_internal(std::forward<KeyType>(key));
20698 }
20699
20702 void erase(const size_type idx)
20703 {
20704 // this erase only works for arrays
20706 {
20707 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20708 {
20709 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20710 }
20711
20712 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20713 }
20714 else
20715 {
20716 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20717 }
20718 }
20719
20721
20722
20724 // lookup //
20726
20729
20732 iterator find(const typename object_t::key_type& key)
20733 {
20734 auto result = end();
20735
20736 if (is_object())
20737 {
20738 result.m_it.object_iterator = m_value.object->find(key);
20739 }
20740
20741 return result;
20742 }
20743
20746 const_iterator find(const typename object_t::key_type& key) const
20747 {
20748 auto result = cend();
20749
20750 if (is_object())
20751 {
20752 result.m_it.object_iterator = m_value.object->find(key);
20753 }
20754
20755 return result;
20756 }
20757
20760 template<class KeyType, detail::enable_if_t<
20762 iterator find(KeyType && key)
20763 {
20764 auto result = end();
20765
20766 if (is_object())
20767 {
20768 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
20769 }
20770
20771 return result;
20772 }
20773
20776 template<class KeyType, detail::enable_if_t<
20778 const_iterator find(KeyType && key) const
20779 {
20780 auto result = cend();
20781
20782 if (is_object())
20783 {
20784 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
20785 }
20786
20787 return result;
20788 }
20789
20792 size_type count(const typename object_t::key_type& key) const
20793 {
20794 // return 0 for all nonobject types
20795 return is_object() ? m_value.object->count(key) : 0;
20796 }
20797
20800 template<class KeyType, detail::enable_if_t<
20802 size_type count(KeyType && key) const
20803 {
20804 // return 0 for all nonobject types
20805 return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
20806 }
20807
20810 bool contains(const typename object_t::key_type& key) const
20811 {
20812 return is_object() && m_value.object->find(key) != m_value.object->end();
20813 }
20814
20817 template<class KeyType, detail::enable_if_t<
20819 bool contains(KeyType && key) const
20820 {
20821 return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
20822 }
20823
20826 bool contains(const json_pointer& ptr) const
20827 {
20828 return ptr.contains(this);
20829 }
20830
20831 template<typename BasicJsonType>
20833 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType> ptr) const
20834 {
20835 return ptr.contains(this);
20836 }
20837
20839
20840
20842 // iterators //
20844
20847
20850 iterator begin() noexcept
20851 {
20852 iterator result(this);
20853 result.set_begin();
20854 return result;
20855 }
20856
20859 const_iterator begin() const noexcept
20860 {
20861 return cbegin();
20862 }
20863
20866 const_iterator cbegin() const noexcept
20867 {
20868 const_iterator result(this);
20869 result.set_begin();
20870 return result;
20871 }
20872
20875 iterator end() noexcept
20876 {
20877 iterator result(this);
20878 result.set_end();
20879 return result;
20880 }
20881
20884 const_iterator end() const noexcept
20885 {
20886 return cend();
20887 }
20888
20891 const_iterator cend() const noexcept
20892 {
20893 const_iterator result(this);
20894 result.set_end();
20895 return result;
20896 }
20897
20900 reverse_iterator rbegin() noexcept
20901 {
20902 return reverse_iterator(end());
20903 }
20904
20907 const_reverse_iterator rbegin() const noexcept
20908 {
20909 return crbegin();
20910 }
20911
20914 reverse_iterator rend() noexcept
20915 {
20916 return reverse_iterator(begin());
20917 }
20918
20921 const_reverse_iterator rend() const noexcept
20922 {
20923 return crend();
20924 }
20925
20928 const_reverse_iterator crbegin() const noexcept
20929 {
20930 return const_reverse_iterator(cend());
20931 }
20932
20935 const_reverse_iterator crend() const noexcept
20936 {
20937 return const_reverse_iterator(cbegin());
20938 }
20939
20940 public:
20946 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
20947 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
20948 {
20949 return ref.items();
20950 }
20951
20957 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
20958 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
20959 {
20960 return ref.items();
20961 }
20962
20965 iteration_proxy<iterator> items() noexcept
20966 {
20967 return iteration_proxy<iterator>(*this);
20968 }
20969
20972 iteration_proxy<const_iterator> items() const noexcept
20973 {
20974 return iteration_proxy<const_iterator>(*this);
20975 }
20976
20978
20979
20981 // capacity //
20983
20986
20989 bool empty() const noexcept
20990 {
20991 switch (m_type)
20992 {
20993 case value_t::null:
20994 {
20995 // null values are empty
20996 return true;
20997 }
20998
20999 case value_t::array:
21000 {
21001 // delegate call to array_t::empty()
21002 return m_value.array->empty();
21003 }
21004
21005 case value_t::object:
21006 {
21007 // delegate call to object_t::empty()
21008 return m_value.object->empty();
21009 }
21010
21011 case value_t::string:
21012 case value_t::boolean:
21016 case value_t::binary:
21017 case value_t::discarded:
21018 default:
21019 {
21020 // all other types are nonempty
21021 return false;
21022 }
21023 }
21024 }
21025
21028 size_type size() const noexcept
21029 {
21030 switch (m_type)
21031 {
21032 case value_t::null:
21033 {
21034 // null values are empty
21035 return 0;
21036 }
21037
21038 case value_t::array:
21039 {
21040 // delegate call to array_t::size()
21041 return m_value.array->size();
21042 }
21043
21044 case value_t::object:
21045 {
21046 // delegate call to object_t::size()
21047 return m_value.object->size();
21048 }
21049
21050 case value_t::string:
21051 case value_t::boolean:
21055 case value_t::binary:
21056 case value_t::discarded:
21057 default:
21058 {
21059 // all other types have size 1
21060 return 1;
21061 }
21062 }
21063 }
21064
21067 size_type max_size() const noexcept
21068 {
21069 switch (m_type)
21070 {
21071 case value_t::array:
21072 {
21073 // delegate call to array_t::max_size()
21074 return m_value.array->max_size();
21075 }
21076
21077 case value_t::object:
21078 {
21079 // delegate call to object_t::max_size()
21080 return m_value.object->max_size();
21081 }
21082
21083 case value_t::null:
21084 case value_t::string:
21085 case value_t::boolean:
21089 case value_t::binary:
21090 case value_t::discarded:
21091 default:
21092 {
21093 // all other types have max_size() == size()
21094 return size();
21095 }
21096 }
21097 }
21098
21100
21101
21103 // modifiers //
21105
21108
21111 void clear() noexcept
21112 {
21113 switch (m_type)
21114 {
21116 {
21117 m_value.number_integer = 0;
21118 break;
21119 }
21120
21122 {
21123 m_value.number_unsigned = 0;
21124 break;
21125 }
21126
21128 {
21129 m_value.number_float = 0.0;
21130 break;
21131 }
21132
21133 case value_t::boolean:
21134 {
21135 m_value.boolean = false;
21136 break;
21137 }
21138
21139 case value_t::string:
21140 {
21141 m_value.string->clear();
21142 break;
21143 }
21144
21145 case value_t::binary:
21146 {
21147 m_value.binary->clear();
21148 break;
21149 }
21150
21151 case value_t::array:
21152 {
21153 m_value.array->clear();
21154 break;
21155 }
21156
21157 case value_t::object:
21158 {
21159 m_value.object->clear();
21160 break;
21161 }
21162
21163 case value_t::null:
21164 case value_t::discarded:
21165 default:
21166 break;
21167 }
21168 }
21169
21172 void push_back(basic_json&& val)
21173 {
21174 // push_back only works for null objects or arrays
21175 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21176 {
21177 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21178 }
21179
21180 // transform null object into an array
21181 if (is_null())
21182 {
21183 m_type = value_t::array;
21185 assert_invariant();
21186 }
21187
21188 // add element to array (move semantics)
21189 const auto old_capacity = m_value.array->capacity();
21190 m_value.array->push_back(std::move(val));
21191 set_parent(m_value.array->back(), old_capacity);
21192 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
21193 }
21194
21198 {
21199 push_back(std::move(val));
21200 return *this;
21201 }
21202
21205 void push_back(const basic_json& val)
21206 {
21207 // push_back only works for null objects or arrays
21208 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21209 {
21210 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21211 }
21212
21213 // transform null object into an array
21214 if (is_null())
21215 {
21216 m_type = value_t::array;
21218 assert_invariant();
21219 }
21220
21221 // add element to array
21222 const auto old_capacity = m_value.array->capacity();
21223 m_value.array->push_back(val);
21224 set_parent(m_value.array->back(), old_capacity);
21225 }
21226
21230 {
21231 push_back(val);
21232 return *this;
21233 }
21234
21237 void push_back(const typename object_t::value_type& val)
21238 {
21239 // push_back only works for null objects or objects
21240 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21241 {
21242 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21243 }
21244
21245 // transform null object into an object
21246 if (is_null())
21247 {
21248 m_type = value_t::object;
21250 assert_invariant();
21251 }
21252
21253 // add element to object
21254 auto res = m_value.object->insert(val);
21255 set_parent(res.first->second);
21256 }
21257
21260 reference operator+=(const typename object_t::value_type& val)
21261 {
21262 push_back(val);
21263 return *this;
21264 }
21265
21269 {
21270 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21271 {
21272 basic_json&& key = init.begin()->moved_or_copied();
21273 push_back(typename object_t::value_type(
21274 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21275 }
21276 else
21277 {
21278 push_back(basic_json(init));
21279 }
21280 }
21281
21285 {
21286 push_back(init);
21287 return *this;
21288 }
21289
21292 template<class... Args>
21293 reference emplace_back(Args&& ... args)
21294 {
21295 // emplace_back only works for null objects or arrays
21296 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21297 {
21298 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
21299 }
21300
21301 // transform null object into an array
21302 if (is_null())
21303 {
21304 m_type = value_t::array;
21306 assert_invariant();
21307 }
21308
21309 // add element to array (perfect forwarding)
21310 const auto old_capacity = m_value.array->capacity();
21311 m_value.array->emplace_back(std::forward<Args>(args)...);
21312 return set_parent(m_value.array->back(), old_capacity);
21313 }
21314
21317 template<class... Args>
21318 std::pair<iterator, bool> emplace(Args&& ... args)
21319 {
21320 // emplace only works for null objects or arrays
21321 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21322 {
21323 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
21324 }
21325
21326 // transform null object into an object
21327 if (is_null())
21328 {
21329 m_type = value_t::object;
21331 assert_invariant();
21332 }
21333
21334 // add element to array (perfect forwarding)
21335 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21336 set_parent(res.first->second);
21337
21338 // create result iterator and set iterator to the result of emplace
21339 auto it = begin();
21340 it.m_it.object_iterator = res.first;
21341
21342 // return pair of iterator and boolean
21343 return {it, res.second};
21344 }
21345
21349 template<typename... Args>
21351 {
21352 iterator result(this);
21353 JSON_ASSERT(m_value.array != nullptr);
21354
21355 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21356 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21357 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21358
21359 // This could have been written as:
21360 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21361 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21362
21363 set_parents();
21364 return result;
21365 }
21366
21370 {
21371 // insert only works for arrays
21373 {
21374 // check if iterator pos fits to this JSON value
21375 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21376 {
21377 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21378 }
21379
21380 // insert to array and return iterator
21381 return insert_iterator(pos, val);
21382 }
21383
21384 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21385 }
21386
21390 {
21391 return insert(pos, val);
21392 }
21393
21397 {
21398 // insert only works for arrays
21400 {
21401 // check if iterator pos fits to this JSON value
21402 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21403 {
21404 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21405 }
21406
21407 // insert to array and return iterator
21408 return insert_iterator(pos, cnt, val);
21409 }
21410
21411 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21412 }
21413
21417 {
21418 // insert only works for arrays
21420 {
21421 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21422 }
21423
21424 // check if iterator pos fits to this JSON value
21425 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21426 {
21427 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21428 }
21429
21430 // check if range iterators belong to the same JSON object
21431 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21432 {
21433 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21434 }
21435
21436 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21437 {
21438 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
21439 }
21440
21441 // insert to array and return iterator
21442 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21443 }
21444
21448 {
21449 // insert only works for arrays
21451 {
21452 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21453 }
21454
21455 // check if iterator pos fits to this JSON value
21456 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21457 {
21458 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21459 }
21460
21461 // insert to array and return iterator
21462 return insert_iterator(pos, ilist.begin(), ilist.end());
21463 }
21464
21468 {
21469 // insert only works for objects
21471 {
21472 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21473 }
21474
21475 // check if range iterators belong to the same JSON object
21476 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21477 {
21478 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21479 }
21480
21481 // passed iterators must belong to objects
21482 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21483 {
21484 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
21485 }
21486
21487 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21488 }
21489
21492 void update(const_reference j, bool merge_objects = false)
21493 {
21494 update(j.begin(), j.end(), merge_objects);
21495 }
21496
21499 void update(const_iterator first, const_iterator last, bool merge_objects = false)
21500 {
21501 // implicitly convert null value to an empty object
21502 if (is_null())
21503 {
21504 m_type = value_t::object;
21505 m_value.object = create<object_t>();
21506 assert_invariant();
21507 }
21508
21510 {
21511 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
21512 }
21513
21514 // check if range iterators belong to the same JSON object
21515 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21516 {
21517 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21518 }
21519
21520 // passed iterators must belong to objects
21521 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21522 {
21523 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
21524 }
21525
21526 for (auto it = first; it != last; ++it)
21527 {
21528 if (merge_objects && it.value().is_object())
21529 {
21530 auto it2 = m_value.object->find(it.key());
21531 if (it2 != m_value.object->end())
21532 {
21533 it2->second.update(it.value(), true);
21534 continue;
21535 }
21536 }
21537 m_value.object->operator[](it.key()) = it.value();
21538#if JSON_DIAGNOSTICS
21539 m_value.object->operator[](it.key()).m_parent = this;
21540#endif
21541 }
21542 }
21543
21546 void swap(reference other) noexcept (
21547 std::is_nothrow_move_constructible<value_t>::value&&
21548 std::is_nothrow_move_assignable<value_t>::value&&
21549 std::is_nothrow_move_constructible<json_value>::value&&
21550 std::is_nothrow_move_assignable<json_value>::value
21551 )
21552 {
21553 std::swap(m_type, other.m_type);
21554 std::swap(m_value, other.m_value);
21555
21556 set_parents();
21557 other.set_parents();
21558 assert_invariant();
21559 }
21560
21563 friend void swap(reference left, reference right) noexcept (
21564 std::is_nothrow_move_constructible<value_t>::value&&
21565 std::is_nothrow_move_assignable<value_t>::value&&
21566 std::is_nothrow_move_constructible<json_value>::value&&
21567 std::is_nothrow_move_assignable<json_value>::value
21568 )
21569 {
21570 left.swap(right);
21571 }
21572
21575 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
21576 {
21577 // swap only works for arrays
21579 {
21580 std::swap(*(m_value.array), other);
21581 }
21582 else
21583 {
21584 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21585 }
21586 }
21587
21590 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
21591 {
21592 // swap only works for objects
21594 {
21595 std::swap(*(m_value.object), other);
21596 }
21597 else
21598 {
21599 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21600 }
21601 }
21602
21605 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
21606 {
21607 // swap only works for strings
21609 {
21610 std::swap(*(m_value.string), other);
21611 }
21612 else
21613 {
21614 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21615 }
21616 }
21617
21620 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
21621 {
21622 // swap only works for strings
21624 {
21625 std::swap(*(m_value.binary), other);
21626 }
21627 else
21628 {
21629 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21630 }
21631 }
21632
21635 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
21636 {
21637 // swap only works for strings
21639 {
21640 std::swap(*(m_value.binary), other);
21641 }
21642 else
21643 {
21644 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21645 }
21646 }
21647
21649
21650 public:
21652 // lexicographical comparison operators //
21654
21657
21660 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
21661 {
21662#ifdef __GNUC__
21663#pragma GCC diagnostic push
21664#pragma GCC diagnostic ignored "-Wfloat-equal"
21665#endif
21666 const auto lhs_type = lhs.type();
21667 const auto rhs_type = rhs.type();
21668
21669 if (lhs_type == rhs_type)
21670 {
21671 switch (lhs_type)
21672 {
21673 case value_t::array:
21674 return *lhs.m_value.array == *rhs.m_value.array;
21675
21676 case value_t::object:
21677 return *lhs.m_value.object == *rhs.m_value.object;
21678
21679 case value_t::null:
21680 return true;
21681
21682 case value_t::string:
21683 return *lhs.m_value.string == *rhs.m_value.string;
21684
21685 case value_t::boolean:
21686 return lhs.m_value.boolean == rhs.m_value.boolean;
21687
21689 return lhs.m_value.number_integer == rhs.m_value.number_integer;
21690
21692 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21693
21695 return lhs.m_value.number_float == rhs.m_value.number_float;
21696
21697 case value_t::binary:
21698 return *lhs.m_value.binary == *rhs.m_value.binary;
21699
21700 case value_t::discarded:
21701 default:
21702 return false;
21703 }
21704 }
21705 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
21706 {
21707 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21708 }
21709 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
21710 {
21711 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
21712 }
21713 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
21714 {
21715 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21716 }
21717 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
21718 {
21719 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
21720 }
21721 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
21722 {
21723 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21724 }
21725 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
21726 {
21727 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21728 }
21729
21730 return false;
21731#ifdef __GNUC__
21732#pragma GCC diagnostic pop
21733#endif
21734 }
21735
21738 template<typename ScalarType, typename std::enable_if<
21739 std::is_scalar<ScalarType>::value, int>::type = 0>
21740 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
21741 {
21742 return lhs == basic_json(rhs);
21743 }
21744
21747 template<typename ScalarType, typename std::enable_if<
21748 std::is_scalar<ScalarType>::value, int>::type = 0>
21749 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
21750 {
21751 return basic_json(lhs) == rhs;
21752 }
21753
21756 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
21757 {
21758 return !(lhs == rhs);
21759 }
21760
21763 template<typename ScalarType, typename std::enable_if<
21764 std::is_scalar<ScalarType>::value, int>::type = 0>
21765 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
21766 {
21767 return lhs != basic_json(rhs);
21768 }
21769
21772 template<typename ScalarType, typename std::enable_if<
21773 std::is_scalar<ScalarType>::value, int>::type = 0>
21774 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
21775 {
21776 return basic_json(lhs) != rhs;
21777 }
21778
21781 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
21782 {
21783 const auto lhs_type = lhs.type();
21784 const auto rhs_type = rhs.type();
21785
21786 if (lhs_type == rhs_type)
21787 {
21788 switch (lhs_type)
21789 {
21790 case value_t::array:
21791 // note parentheses are necessary, see
21792 // https://github.com/nlohmann/json/issues/1530
21793 return (*lhs.m_value.array) < (*rhs.m_value.array);
21794
21795 case value_t::object:
21796 return (*lhs.m_value.object) < (*rhs.m_value.object);
21797
21798 case value_t::null:
21799 return false;
21800
21801 case value_t::string:
21802 return (*lhs.m_value.string) < (*rhs.m_value.string);
21803
21804 case value_t::boolean:
21805 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
21806
21808 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
21809
21811 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
21812
21814 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
21815
21816 case value_t::binary:
21817 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
21818
21819 case value_t::discarded:
21820 default:
21821 return false;
21822 }
21823 }
21824 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
21825 {
21826 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
21827 }
21828 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
21829 {
21830 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
21831 }
21832 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
21833 {
21834 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
21835 }
21836 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
21837 {
21838 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
21839 }
21840 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
21841 {
21842 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21843 }
21844 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
21845 {
21846 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
21847 }
21848
21849 // We only reach this line if we cannot compare values. In that case,
21850 // we compare types. Note we have to call the operator explicitly,
21851 // because MSVC has problems otherwise.
21852 return operator<(lhs_type, rhs_type);
21853 }
21854
21857 template<typename ScalarType, typename std::enable_if<
21858 std::is_scalar<ScalarType>::value, int>::type = 0>
21859 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
21860 {
21861 return lhs < basic_json(rhs);
21862 }
21863
21866 template<typename ScalarType, typename std::enable_if<
21867 std::is_scalar<ScalarType>::value, int>::type = 0>
21868 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
21869 {
21870 return basic_json(lhs) < rhs;
21871 }
21872
21875 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
21876 {
21877 return !(rhs < lhs);
21878 }
21879
21882 template<typename ScalarType, typename std::enable_if<
21883 std::is_scalar<ScalarType>::value, int>::type = 0>
21884 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
21885 {
21886 return lhs <= basic_json(rhs);
21887 }
21888
21891 template<typename ScalarType, typename std::enable_if<
21892 std::is_scalar<ScalarType>::value, int>::type = 0>
21893 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
21894 {
21895 return basic_json(lhs) <= rhs;
21896 }
21897
21900 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
21901 {
21902 return !(lhs <= rhs);
21903 }
21904
21907 template<typename ScalarType, typename std::enable_if<
21908 std::is_scalar<ScalarType>::value, int>::type = 0>
21909 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
21910 {
21911 return lhs > basic_json(rhs);
21912 }
21913
21916 template<typename ScalarType, typename std::enable_if<
21917 std::is_scalar<ScalarType>::value, int>::type = 0>
21918 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
21919 {
21920 return basic_json(lhs) > rhs;
21921 }
21922
21925 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
21926 {
21927 return !(lhs < rhs);
21928 }
21929
21932 template<typename ScalarType, typename std::enable_if<
21933 std::is_scalar<ScalarType>::value, int>::type = 0>
21934 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
21935 {
21936 return lhs >= basic_json(rhs);
21937 }
21938
21941 template<typename ScalarType, typename std::enable_if<
21942 std::is_scalar<ScalarType>::value, int>::type = 0>
21943 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
21944 {
21945 return basic_json(lhs) >= rhs;
21946 }
21947
21949
21951 // serialization //
21953
21956#ifndef JSON_NO_IO
21959 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
21960 {
21961 // read width member and use it as indentation parameter if nonzero
21962 const bool pretty_print = o.width() > 0;
21963 const auto indentation = pretty_print ? o.width() : 0;
21964
21965 // reset width to 0 for subsequent calls to this stream
21966 o.width(0);
21967
21968 // do the actual serialization
21969 serializer s(detail::output_adapter<char>(o), o.fill());
21970 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
21971 return o;
21972 }
21973
21980 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
21981 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
21982 {
21983 return o << j;
21984 }
21985#endif // JSON_NO_IO
21987
21988
21990 // deserialization //
21992
21995
21998 template<typename InputType>
22000 static basic_json parse(InputType&& i,
22001 const parser_callback_t cb = nullptr,
22002 const bool allow_exceptions = true,
22003 const bool ignore_comments = false)
22004 {
22005 basic_json result;
22006 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
22007 return result;
22008 }
22009
22012 template<typename IteratorType>
22014 static basic_json parse(IteratorType first,
22015 IteratorType last,
22016 const parser_callback_t cb = nullptr,
22017 const bool allow_exceptions = true,
22018 const bool ignore_comments = false)
22019 {
22020 basic_json result;
22021 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
22022 return result;
22023 }
22024
22026 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
22027 static basic_json parse(detail::span_input_adapter&& i,
22028 const parser_callback_t cb = nullptr,
22029 const bool allow_exceptions = true,
22030 const bool ignore_comments = false)
22031 {
22032 basic_json result;
22033 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
22034 return result;
22035 }
22036
22039 template<typename InputType>
22040 static bool accept(InputType&& i,
22041 const bool ignore_comments = false)
22042 {
22043 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
22044 }
22045
22048 template<typename IteratorType>
22049 static bool accept(IteratorType first, IteratorType last,
22050 const bool ignore_comments = false)
22051 {
22052 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
22053 }
22054
22056 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
22057 static bool accept(detail::span_input_adapter&& i,
22058 const bool ignore_comments = false)
22059 {
22060 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
22061 }
22062
22065 template <typename InputType, typename SAX>
22067 static bool sax_parse(InputType&& i, SAX* sax,
22069 const bool strict = true,
22070 const bool ignore_comments = false)
22071 {
22072 auto ia = detail::input_adapter(std::forward<InputType>(i));
22073 return format == input_format_t::json
22074 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22075 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22076 }
22077
22080 template<class IteratorType, class SAX>
22082 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
22084 const bool strict = true,
22085 const bool ignore_comments = false)
22086 {
22087 auto ia = detail::input_adapter(std::move(first), std::move(last));
22088 return format == input_format_t::json
22089 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22090 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22091 }
22092
22098 template <typename SAX>
22099 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
22101 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22103 const bool strict = true,
22104 const bool ignore_comments = false)
22105 {
22106 auto ia = i.get();
22107 return format == input_format_t::json
22108 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22109 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22110 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22111 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22112 }
22113#ifndef JSON_NO_IO
22120 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
22121 friend std::istream& operator<<(basic_json& j, std::istream& i)
22122 {
22123 return operator>>(i, j);
22124 }
22125
22128 friend std::istream& operator>>(std::istream& i, basic_json& j)
22129 {
22130 parser(detail::input_adapter(i)).parse(false, j);
22131 return i;
22132 }
22133#endif // JSON_NO_IO
22135
22137 // convenience functions //
22139
22143 const char* type_name() const noexcept
22144 {
22145 switch (m_type)
22146 {
22147 case value_t::null:
22148 return "null";
22149 case value_t::object:
22150 return "object";
22151 case value_t::array:
22152 return "array";
22153 case value_t::string:
22154 return "string";
22155 case value_t::boolean:
22156 return "boolean";
22157 case value_t::binary:
22158 return "binary";
22159 case value_t::discarded:
22160 return "discarded";
22164 default:
22165 return "number";
22166 }
22167 }
22168
22169
22172 // member variables //
22174
22176 value_t m_type = value_t::null;
22177
22179 json_value m_value = {};
22180
22181#if JSON_DIAGNOSTICS
22183 basic_json* m_parent = nullptr;
22184#endif
22185
22187 // binary serialization/deserialization //
22189
22192
22193 public:
22196 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
22197 {
22198 std::vector<std::uint8_t> result;
22199 to_cbor(j, result);
22200 return result;
22201 }
22202
22206 {
22208 }
22209
22213 {
22215 }
22216
22219 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
22220 {
22221 std::vector<std::uint8_t> result;
22222 to_msgpack(j, result);
22223 return result;
22224 }
22225
22229 {
22231 }
22232
22236 {
22238 }
22239
22242 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
22243 const bool use_size = false,
22244 const bool use_type = false)
22245 {
22246 std::vector<std::uint8_t> result;
22247 to_ubjson(j, result, use_size, use_type);
22248 return result;
22249 }
22250
22254 const bool use_size = false, const bool use_type = false)
22255 {
22256 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
22257 }
22258
22262 const bool use_size = false, const bool use_type = false)
22263 {
22264 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
22265 }
22266
22269 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
22270 const bool use_size = false,
22271 const bool use_type = false)
22272 {
22273 std::vector<std::uint8_t> result;
22274 to_bjdata(j, result, use_size, use_type);
22275 return result;
22276 }
22277
22281 const bool use_size = false, const bool use_type = false)
22282 {
22283 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
22284 }
22285
22289 const bool use_size = false, const bool use_type = false)
22290 {
22291 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
22292 }
22293
22296 static std::vector<std::uint8_t> to_bson(const basic_json& j)
22297 {
22298 std::vector<std::uint8_t> result;
22299 to_bson(j, result);
22300 return result;
22301 }
22302
22306 {
22308 }
22309
22313 {
22315 }
22316
22319 template<typename InputType>
22321 static basic_json from_cbor(InputType&& i,
22322 const bool strict = true,
22323 const bool allow_exceptions = true,
22324 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22325 {
22326 basic_json result;
22327 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22328 auto ia = detail::input_adapter(std::forward<InputType>(i));
22329 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22330 return res ? result : basic_json(value_t::discarded);
22331 }
22332
22335 template<typename IteratorType>
22337 static basic_json from_cbor(IteratorType first, IteratorType last,
22338 const bool strict = true,
22339 const bool allow_exceptions = true,
22340 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22341 {
22342 basic_json result;
22343 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22344 auto ia = detail::input_adapter(std::move(first), std::move(last));
22345 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22346 return res ? result : basic_json(value_t::discarded);
22347 }
22348
22349 template<typename T>
22351 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22352 static basic_json from_cbor(const T* ptr, std::size_t len,
22353 const bool strict = true,
22354 const bool allow_exceptions = true,
22355 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22356 {
22357 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
22358 }
22359
22360
22362 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22363 static basic_json from_cbor(detail::span_input_adapter&& i,
22364 const bool strict = true,
22365 const bool allow_exceptions = true,
22366 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22367 {
22368 basic_json result;
22369 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22370 auto ia = i.get();
22371 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22372 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22373 return res ? result : basic_json(value_t::discarded);
22374 }
22375
22378 template<typename InputType>
22380 static basic_json from_msgpack(InputType&& i,
22381 const bool strict = true,
22382 const bool allow_exceptions = true)
22383 {
22384 basic_json result;
22385 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22386 auto ia = detail::input_adapter(std::forward<InputType>(i));
22387 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22388 return res ? result : basic_json(value_t::discarded);
22389 }
22390
22393 template<typename IteratorType>
22395 static basic_json from_msgpack(IteratorType first, IteratorType last,
22396 const bool strict = true,
22397 const bool allow_exceptions = true)
22398 {
22399 basic_json result;
22400 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22401 auto ia = detail::input_adapter(std::move(first), std::move(last));
22402 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22403 return res ? result : basic_json(value_t::discarded);
22404 }
22405
22406 template<typename T>
22408 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22409 static basic_json from_msgpack(const T* ptr, std::size_t len,
22410 const bool strict = true,
22411 const bool allow_exceptions = true)
22412 {
22413 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
22414 }
22415
22417 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22418 static basic_json from_msgpack(detail::span_input_adapter&& i,
22419 const bool strict = true,
22420 const bool allow_exceptions = true)
22421 {
22422 basic_json result;
22423 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22424 auto ia = i.get();
22425 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22426 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22427 return res ? result : basic_json(value_t::discarded);
22428 }
22429
22432 template<typename InputType>
22434 static basic_json from_ubjson(InputType&& i,
22435 const bool strict = true,
22436 const bool allow_exceptions = true)
22437 {
22438 basic_json result;
22439 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22440 auto ia = detail::input_adapter(std::forward<InputType>(i));
22441 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22442 return res ? result : basic_json(value_t::discarded);
22443 }
22444
22447 template<typename IteratorType>
22449 static basic_json from_ubjson(IteratorType first, IteratorType last,
22450 const bool strict = true,
22451 const bool allow_exceptions = true)
22452 {
22453 basic_json result;
22454 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22455 auto ia = detail::input_adapter(std::move(first), std::move(last));
22456 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22457 return res ? result : basic_json(value_t::discarded);
22458 }
22459
22460 template<typename T>
22462 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22463 static basic_json from_ubjson(const T* ptr, std::size_t len,
22464 const bool strict = true,
22465 const bool allow_exceptions = true)
22466 {
22467 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
22468 }
22469
22471 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22472 static basic_json from_ubjson(detail::span_input_adapter&& i,
22473 const bool strict = true,
22474 const bool allow_exceptions = true)
22475 {
22476 basic_json result;
22477 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22478 auto ia = i.get();
22479 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22480 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22481 return res ? result : basic_json(value_t::discarded);
22482 }
22483
22484
22487 template<typename InputType>
22489 static basic_json from_bjdata(InputType&& i,
22490 const bool strict = true,
22491 const bool allow_exceptions = true)
22492 {
22493 basic_json result;
22494 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22495 auto ia = detail::input_adapter(std::forward<InputType>(i));
22496 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22497 return res ? result : basic_json(value_t::discarded);
22498 }
22499
22502 template<typename IteratorType>
22504 static basic_json from_bjdata(IteratorType first, IteratorType last,
22505 const bool strict = true,
22506 const bool allow_exceptions = true)
22507 {
22508 basic_json result;
22509 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22510 auto ia = detail::input_adapter(std::move(first), std::move(last));
22511 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22512 return res ? result : basic_json(value_t::discarded);
22513 }
22514
22515 template<typename T>
22517 static basic_json from_bjdata(const T* ptr, std::size_t len,
22518 const bool strict = true,
22519 const bool allow_exceptions = true)
22520 {
22521 return from_bjdata(ptr, ptr + len, strict, allow_exceptions);
22522 }
22523
22526 const bool strict = true,
22527 const bool allow_exceptions = true)
22528 {
22529 basic_json result;
22530 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22531 auto ia = i.get();
22532 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22533 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22534 return res ? result : basic_json(value_t::discarded);
22535 }
22536
22537
22540 template<typename InputType>
22542 static basic_json from_bson(InputType&& i,
22543 const bool strict = true,
22544 const bool allow_exceptions = true)
22545 {
22546 basic_json result;
22547 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22548 auto ia = detail::input_adapter(std::forward<InputType>(i));
22549 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22550 return res ? result : basic_json(value_t::discarded);
22551 }
22552
22555 template<typename IteratorType>
22557 static basic_json from_bson(IteratorType first, IteratorType last,
22558 const bool strict = true,
22559 const bool allow_exceptions = true)
22560 {
22561 basic_json result;
22562 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22563 auto ia = detail::input_adapter(std::move(first), std::move(last));
22564 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22565 return res ? result : basic_json(value_t::discarded);
22566 }
22567
22568 template<typename T>
22570 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
22571 static basic_json from_bson(const T* ptr, std::size_t len,
22572 const bool strict = true,
22573 const bool allow_exceptions = true)
22574 {
22575 return from_bson(ptr, ptr + len, strict, allow_exceptions);
22576 }
22577
22579 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
22580 static basic_json from_bson(detail::span_input_adapter&& i,
22581 const bool strict = true,
22582 const bool allow_exceptions = true)
22583 {
22584 basic_json result;
22585 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22586 auto ia = i.get();
22587 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22588 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22589 return res ? result : basic_json(value_t::discarded);
22590 }
22592
22594 // JSON Pointer support //
22596
22599
22603 {
22604 return ptr.get_unchecked(this);
22605 }
22606
22607 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22609 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
22610 {
22611 return ptr.get_unchecked(this);
22612 }
22613
22617 {
22618 return ptr.get_unchecked(this);
22619 }
22620
22621 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22623 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22624 {
22625 return ptr.get_unchecked(this);
22626 }
22627
22630 reference at(const json_pointer& ptr)
22631 {
22632 return ptr.get_checked(this);
22633 }
22634
22635 template<typename BasicJsonType>
22637 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
22638 {
22639 return ptr.get_checked(this);
22640 }
22641
22645 {
22646 return ptr.get_checked(this);
22647 }
22648
22649 template<typename BasicJsonType>
22651 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22652 {
22653 return ptr.get_checked(this);
22654 }
22655
22658 basic_json flatten() const
22659 {
22661 json_pointer::flatten("", *this, result);
22662 return result;
22663 }
22664
22667 basic_json unflatten() const
22668 {
22669 return json_pointer::unflatten(*this);
22670 }
22671
22673
22675 // JSON Patch functions //
22677
22680
22683 basic_json patch(const basic_json& json_patch) const
22684 {
22685 // make a working copy to apply the patch to
22686 basic_json result = *this;
22687
22688 // the valid JSON Patch operations
22689 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
22690
22691 const auto get_op = [](const std::string & op)
22692 {
22693 if (op == "add")
22694 {
22695 return patch_operations::add;
22696 }
22697 if (op == "remove")
22698 {
22699 return patch_operations::remove;
22700 }
22701 if (op == "replace")
22702 {
22703 return patch_operations::replace;
22704 }
22705 if (op == "move")
22706 {
22707 return patch_operations::move;
22708 }
22709 if (op == "copy")
22710 {
22711 return patch_operations::copy;
22712 }
22713 if (op == "test")
22714 {
22715 return patch_operations::test;
22716 }
22717
22718 return patch_operations::invalid;
22719 };
22720
22721 // wrapper for "add" operation; add value at ptr
22722 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
22723 {
22724 // adding to the root of the target document means replacing it
22725 if (ptr.empty())
22726 {
22727 result = val;
22728 return;
22729 }
22730
22731 // make sure the top element of the pointer exists
22732 json_pointer top_pointer = ptr.top();
22733 if (top_pointer != ptr)
22734 {
22735 result.at(top_pointer);
22736 }
22737
22738 // get reference to parent of JSON pointer ptr
22739 const auto last_path = ptr.back();
22740 ptr.pop_back();
22741 basic_json& parent = result[ptr];
22742
22743 switch (parent.m_type)
22744 {
22745 case value_t::null:
22746 case value_t::object:
22747 {
22748 // use operator[] to add value
22749 parent[last_path] = val;
22750 break;
22751 }
22752
22753 case value_t::array:
22754 {
22755 if (last_path == "-")
22756 {
22757 // special case: append to back
22758 parent.push_back(val);
22759 }
22760 else
22761 {
22762 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
22763 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
22764 {
22765 // avoid undefined behavior
22766 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
22767 }
22768
22769 // default case: insert add offset
22770 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
22771 }
22772 break;
22773 }
22774
22775 // if there exists a parent it cannot be primitive
22776 case value_t::string: // LCOV_EXCL_LINE
22777 case value_t::boolean: // LCOV_EXCL_LINE
22778 case value_t::number_integer: // LCOV_EXCL_LINE
22779 case value_t::number_unsigned: // LCOV_EXCL_LINE
22780 case value_t::number_float: // LCOV_EXCL_LINE
22781 case value_t::binary: // LCOV_EXCL_LINE
22782 case value_t::discarded: // LCOV_EXCL_LINE
22783 default: // LCOV_EXCL_LINE
22784 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
22785 }
22786 };
22787
22788 // wrapper for "remove" operation; remove value at ptr
22789 const auto operation_remove = [this, &result](json_pointer & ptr)
22790 {
22791 // get reference to parent of JSON pointer ptr
22792 const auto last_path = ptr.back();
22793 ptr.pop_back();
22794 basic_json& parent = result.at(ptr);
22795
22796 // remove child
22797 if (parent.is_object())
22798 {
22799 // perform range check
22800 auto it = parent.find(last_path);
22801 if (JSON_HEDLEY_LIKELY(it != parent.end()))
22802 {
22803 parent.erase(it);
22804 }
22805 else
22806 {
22807 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
22808 }
22809 }
22810 else if (parent.is_array())
22811 {
22812 // note erase performs range check
22813 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
22814 }
22815 };
22816
22817 // type check: top level value must be an array
22818 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
22819 {
22820 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
22821 }
22822
22823 // iterate and apply the operations
22824 for (const auto& val : json_patch)
22825 {
22826 // wrapper to get a value for an operation
22827 const auto get_value = [&val](const std::string & op,
22828 const std::string & member,
22829 bool string_type) -> basic_json &
22830 {
22831 // find value
22832 auto it = val.m_value.object->find(member);
22833
22834 // context-sensitive error message
22835 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
22836
22837 // check if desired value is present
22838 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
22839 {
22840 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
22841 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
22842 }
22843
22844 // check if result is of type string
22845 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
22846 {
22847 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
22848 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
22849 }
22850
22851 // no error: return value
22852 return it->second;
22853 };
22854
22855 // type check: every element of the array must be an object
22856 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
22857 {
22858 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
22859 }
22860
22861 // collect mandatory members
22862 const auto op = get_value("op", "op", true).template get<std::string>();
22863 const auto path = get_value(op, "path", true).template get<std::string>();
22864 json_pointer ptr(path);
22865
22866 switch (get_op(op))
22867 {
22868 case patch_operations::add:
22869 {
22870 operation_add(ptr, get_value("add", "value", false));
22871 break;
22872 }
22873
22874 case patch_operations::remove:
22875 {
22876 operation_remove(ptr);
22877 break;
22878 }
22879
22880 case patch_operations::replace:
22881 {
22882 // the "path" location must exist - use at()
22883 result.at(ptr) = get_value("replace", "value", false);
22884 break;
22885 }
22886
22887 case patch_operations::move:
22888 {
22889 const auto from_path = get_value("move", "from", true).template get<std::string>();
22890 json_pointer from_ptr(from_path);
22891
22892 // the "from" location must exist - use at()
22893 basic_json v = result.at(from_ptr);
22894
22895 // The move operation is functionally identical to a
22896 // "remove" operation on the "from" location, followed
22897 // immediately by an "add" operation at the target
22898 // location with the value that was just removed.
22899 operation_remove(from_ptr);
22900 operation_add(ptr, v);
22901 break;
22902 }
22903
22904 case patch_operations::copy:
22905 {
22906 const auto from_path = get_value("copy", "from", true).template get<std::string>();
22907 const json_pointer from_ptr(from_path);
22908
22909 // the "from" location must exist - use at()
22910 basic_json v = result.at(from_ptr);
22911
22912 // The copy is functionally identical to an "add"
22913 // operation at the target location using the value
22914 // specified in the "from" member.
22915 operation_add(ptr, v);
22916 break;
22917 }
22918
22919 case patch_operations::test:
22920 {
22921 bool success = false;
22922 JSON_TRY
22923 {
22924 // check if "value" matches the one at "path"
22925 // the "path" location must exist - use at()
22926 success = (result.at(ptr) == get_value("test", "value", false));
22927 }
22929 {
22930 // ignore out of range errors: success remains false
22931 }
22932
22933 // throw an exception if test fails
22934 if (JSON_HEDLEY_UNLIKELY(!success))
22935 {
22936 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
22937 }
22938
22939 break;
22940 }
22941
22942 case patch_operations::invalid:
22943 default:
22944 {
22945 // op must be "add", "remove", "replace", "move", "copy", or
22946 // "test"
22947 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
22948 }
22949 }
22950 }
22951
22952 return result;
22953 }
22954
22958 static basic_json diff(const basic_json& source, const basic_json& target,
22959 const std::string& path = "")
22960 {
22961 // the patch
22962 basic_json result(value_t::array);
22963
22964 // if the values are the same, return empty patch
22965 if (source == target)
22966 {
22967 return result;
22968 }
22969
22970 if (source.type() != target.type())
22971 {
22972 // different types: replace value
22973 result.push_back(
22974 {
22975 {"op", "replace"}, {"path", path}, {"value", target}
22976 });
22977 return result;
22978 }
22979
22980 switch (source.type())
22981 {
22982 case value_t::array:
22983 {
22984 // first pass: traverse common elements
22985 std::size_t i = 0;
22986 while (i < source.size() && i < target.size())
22987 {
22988 // recursive call to compare array values at index i
22989 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
22990 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22991 ++i;
22992 }
22993
22994 // We now reached the end of at least one array
22995 // in a second pass, traverse the remaining elements
22996
22997 // remove my remaining elements
22998 const auto end_index = static_cast<difference_type>(result.size());
22999 while (i < source.size())
23000 {
23001 // add operations in reverse order to avoid invalid
23002 // indices
23003 result.insert(result.begin() + end_index, object(
23004 {
23005 {"op", "remove"},
23006 {"path", detail::concat(path, '/', std::to_string(i))}
23007 }));
23008 ++i;
23009 }
23010
23011 // add other remaining elements
23012 while (i < target.size())
23013 {
23014 result.push_back(
23015 {
23016 {"op", "add"},
23017 {"path", detail::concat(path, "/-")},
23018 {"value", target[i]}
23019 });
23020 ++i;
23021 }
23022
23023 break;
23024 }
23025
23026 case value_t::object:
23027 {
23028 // first pass: traverse this object's elements
23029 for (auto it = source.cbegin(); it != source.cend(); ++it)
23030 {
23031 // escape the key name to be used in a JSON patch
23032 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23033
23034 if (target.find(it.key()) != target.end())
23035 {
23036 // recursive call to compare object values at key it
23037 auto temp_diff = diff(it.value(), target[it.key()], path_key);
23038 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23039 }
23040 else
23041 {
23042 // found a key that is not in o -> remove it
23043 result.push_back(object(
23044 {
23045 {"op", "remove"}, {"path", path_key}
23046 }));
23047 }
23048 }
23049
23050 // second pass: traverse other object's elements
23051 for (auto it = target.cbegin(); it != target.cend(); ++it)
23052 {
23053 if (source.find(it.key()) == source.end())
23054 {
23055 // found a key that is not in this -> add it
23056 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23057 result.push_back(
23058 {
23059 {"op", "add"}, {"path", path_key},
23060 {"value", it.value()}
23061 });
23062 }
23063 }
23064
23065 break;
23066 }
23067
23068 case value_t::null:
23069 case value_t::string:
23070 case value_t::boolean:
23074 case value_t::binary:
23075 case value_t::discarded:
23076 default:
23077 {
23078 // both primitive type: replace value
23079 result.push_back(
23080 {
23081 {"op", "replace"}, {"path", path}, {"value", target}
23082 });
23083 break;
23084 }
23085 }
23086
23087 return result;
23088 }
23089
23091
23093 // JSON Merge Patch functions //
23095
23098
23101 void merge_patch(const basic_json& apply_patch)
23102 {
23103 if (apply_patch.is_object())
23104 {
23105 if (!is_object())
23106 {
23107 *this = object();
23108 }
23109 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
23110 {
23111 if (it.value().is_null())
23112 {
23113 erase(it.key());
23114 }
23115 else
23116 {
23117 operator[](it.key()).merge_patch(it.value());
23118 }
23119 }
23120 }
23121 else
23122 {
23123 *this = apply_patch;
23124 }
23125 }
23126
23128};
23129
23134{
23135 return j.dump();
23136}
23137
23138} // namespace nlohmann
23139
23141// nonmember support //
23143
23144namespace std // NOLINT(cert-dcl58-cpp)
23145{
23146
23151{
23153 {
23154 return nlohmann::detail::hash(j);
23155 }
23156};
23157
23158// specialization for std::less<value_t>
23159template<>
23160struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
23161{
23167 nlohmann::detail::value_t rhs) const noexcept
23168 {
23169 return nlohmann::detail::operator<(lhs, rhs);
23170 }
23171};
23172
23173// C++20 prohibit function specialization in the std namespace.
23174#ifndef JSON_HAS_CPP_20
23175
23179inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
23180 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
23181 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
23182{
23183 j1.swap(j2);
23184}
23185
23186#endif
23187
23188} // namespace std
23189
23193inline nlohmann::json operator "" _json(const char* s, std::size_t n)
23194{
23195 return nlohmann::json::parse(s, s + n);
23196}
23197
23201inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
23202{
23203 return nlohmann::json::json_pointer(std::string(s, n));
23204}
23205
23206// #include <nlohmann/detail/macro_unscope.hpp>
23207
23208
23209// restore clang diagnostic settings
23210#if defined(__clang__)
23211 #pragma clang diagnostic pop
23212#endif
23213
23214// clean up
23215#undef JSON_ASSERT
23216#undef JSON_INTERNAL_CATCH
23217#undef JSON_THROW
23218#undef JSON_PRIVATE_UNLESS_TESTED
23219#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
23220#undef NLOHMANN_BASIC_JSON_TPL
23221#undef JSON_EXPLICIT
23222#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
23223#undef JSON_NO_UNIQUE_ADDRESS
23224
23225#ifndef JSON_TEST_KEEP_MACROS
23226 #undef JSON_CATCH
23227 #undef JSON_TRY
23228 #undef JSON_HAS_CPP_11
23229 #undef JSON_HAS_CPP_14
23230 #undef JSON_HAS_CPP_17
23231 #undef JSON_HAS_CPP_20
23232 #undef JSON_HAS_FILESYSTEM
23233 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
23234 #undef JSON_HAS_THREE_WAY_COMPARISON
23235#endif
23236
23237// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
23238
23239
23240#undef JSON_HEDLEY_ALWAYS_INLINE
23241#undef JSON_HEDLEY_ARM_VERSION
23242#undef JSON_HEDLEY_ARM_VERSION_CHECK
23243#undef JSON_HEDLEY_ARRAY_PARAM
23244#undef JSON_HEDLEY_ASSUME
23245#undef JSON_HEDLEY_BEGIN_C_DECLS
23246#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
23247#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
23248#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
23249#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
23250#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
23251#undef JSON_HEDLEY_CLANG_HAS_FEATURE
23252#undef JSON_HEDLEY_CLANG_HAS_WARNING
23253#undef JSON_HEDLEY_COMPCERT_VERSION
23254#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
23255#undef JSON_HEDLEY_CONCAT
23256#undef JSON_HEDLEY_CONCAT3
23257#undef JSON_HEDLEY_CONCAT3_EX
23258#undef JSON_HEDLEY_CONCAT_EX
23259#undef JSON_HEDLEY_CONST
23260#undef JSON_HEDLEY_CONSTEXPR
23261#undef JSON_HEDLEY_CONST_CAST
23262#undef JSON_HEDLEY_CPP_CAST
23263#undef JSON_HEDLEY_CRAY_VERSION
23264#undef JSON_HEDLEY_CRAY_VERSION_CHECK
23265#undef JSON_HEDLEY_C_DECL
23266#undef JSON_HEDLEY_DEPRECATED
23267#undef JSON_HEDLEY_DEPRECATED_FOR
23268#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
23269#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
23270#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
23271#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
23272#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
23273#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
23274#undef JSON_HEDLEY_DIAGNOSTIC_POP
23275#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
23276#undef JSON_HEDLEY_DMC_VERSION
23277#undef JSON_HEDLEY_DMC_VERSION_CHECK
23278#undef JSON_HEDLEY_EMPTY_BASES
23279#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
23280#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
23281#undef JSON_HEDLEY_END_C_DECLS
23282#undef JSON_HEDLEY_FLAGS
23283#undef JSON_HEDLEY_FLAGS_CAST
23284#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
23285#undef JSON_HEDLEY_GCC_HAS_BUILTIN
23286#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
23287#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
23288#undef JSON_HEDLEY_GCC_HAS_EXTENSION
23289#undef JSON_HEDLEY_GCC_HAS_FEATURE
23290#undef JSON_HEDLEY_GCC_HAS_WARNING
23291#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
23292#undef JSON_HEDLEY_GCC_VERSION
23293#undef JSON_HEDLEY_GCC_VERSION_CHECK
23294#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
23295#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
23296#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
23297#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
23298#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
23299#undef JSON_HEDLEY_GNUC_HAS_FEATURE
23300#undef JSON_HEDLEY_GNUC_HAS_WARNING
23301#undef JSON_HEDLEY_GNUC_VERSION
23302#undef JSON_HEDLEY_GNUC_VERSION_CHECK
23303#undef JSON_HEDLEY_HAS_ATTRIBUTE
23304#undef JSON_HEDLEY_HAS_BUILTIN
23305#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
23306#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
23307#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
23308#undef JSON_HEDLEY_HAS_EXTENSION
23309#undef JSON_HEDLEY_HAS_FEATURE
23310#undef JSON_HEDLEY_HAS_WARNING
23311#undef JSON_HEDLEY_IAR_VERSION
23312#undef JSON_HEDLEY_IAR_VERSION_CHECK
23313#undef JSON_HEDLEY_IBM_VERSION
23314#undef JSON_HEDLEY_IBM_VERSION_CHECK
23315#undef JSON_HEDLEY_IMPORT
23316#undef JSON_HEDLEY_INLINE
23317#undef JSON_HEDLEY_INTEL_CL_VERSION
23318#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
23319#undef JSON_HEDLEY_INTEL_VERSION
23320#undef JSON_HEDLEY_INTEL_VERSION_CHECK
23321#undef JSON_HEDLEY_IS_CONSTANT
23322#undef JSON_HEDLEY_IS_CONSTEXPR_
23323#undef JSON_HEDLEY_LIKELY
23324#undef JSON_HEDLEY_MALLOC
23325#undef JSON_HEDLEY_MCST_LCC_VERSION
23326#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
23327#undef JSON_HEDLEY_MESSAGE
23328#undef JSON_HEDLEY_MSVC_VERSION
23329#undef JSON_HEDLEY_MSVC_VERSION_CHECK
23330#undef JSON_HEDLEY_NEVER_INLINE
23331#undef JSON_HEDLEY_NON_NULL
23332#undef JSON_HEDLEY_NO_ESCAPE
23333#undef JSON_HEDLEY_NO_RETURN
23334#undef JSON_HEDLEY_NO_THROW
23335#undef JSON_HEDLEY_NULL
23336#undef JSON_HEDLEY_PELLES_VERSION
23337#undef JSON_HEDLEY_PELLES_VERSION_CHECK
23338#undef JSON_HEDLEY_PGI_VERSION
23339#undef JSON_HEDLEY_PGI_VERSION_CHECK
23340#undef JSON_HEDLEY_PREDICT
23341#undef JSON_HEDLEY_PRINTF_FORMAT
23342#undef JSON_HEDLEY_PRIVATE
23343#undef JSON_HEDLEY_PUBLIC
23344#undef JSON_HEDLEY_PURE
23345#undef JSON_HEDLEY_REINTERPRET_CAST
23346#undef JSON_HEDLEY_REQUIRE
23347#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
23348#undef JSON_HEDLEY_REQUIRE_MSG
23349#undef JSON_HEDLEY_RESTRICT
23350#undef JSON_HEDLEY_RETURNS_NON_NULL
23351#undef JSON_HEDLEY_SENTINEL
23352#undef JSON_HEDLEY_STATIC_ASSERT
23353#undef JSON_HEDLEY_STATIC_CAST
23354#undef JSON_HEDLEY_STRINGIFY
23355#undef JSON_HEDLEY_STRINGIFY_EX
23356#undef JSON_HEDLEY_SUNPRO_VERSION
23357#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
23358#undef JSON_HEDLEY_TINYC_VERSION
23359#undef JSON_HEDLEY_TINYC_VERSION_CHECK
23360#undef JSON_HEDLEY_TI_ARMCL_VERSION
23361#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
23362#undef JSON_HEDLEY_TI_CL2000_VERSION
23363#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
23364#undef JSON_HEDLEY_TI_CL430_VERSION
23365#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
23366#undef JSON_HEDLEY_TI_CL6X_VERSION
23367#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
23368#undef JSON_HEDLEY_TI_CL7X_VERSION
23369#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
23370#undef JSON_HEDLEY_TI_CLPRU_VERSION
23371#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
23372#undef JSON_HEDLEY_TI_VERSION
23373#undef JSON_HEDLEY_TI_VERSION_CHECK
23374#undef JSON_HEDLEY_UNAVAILABLE
23375#undef JSON_HEDLEY_UNLIKELY
23376#undef JSON_HEDLEY_UNPREDICTABLE
23377#undef JSON_HEDLEY_UNREACHABLE
23378#undef JSON_HEDLEY_UNREACHABLE_RETURN
23379#undef JSON_HEDLEY_VERSION
23380#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
23381#undef JSON_HEDLEY_VERSION_DECODE_MINOR
23382#undef JSON_HEDLEY_VERSION_DECODE_REVISION
23383#undef JSON_HEDLEY_VERSION_ENCODE
23384#undef JSON_HEDLEY_WARNING
23385#undef JSON_HEDLEY_WARN_UNUSED_RESULT
23386#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
23387#undef JSON_HEDLEY_FALL_THROUGH
23388
23389
23390
23391#endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::json json
Definition: API.cpp:15
a class to store JSON values
Definition: json.hpp:18239
ValueType & get_to(ValueType &v) const
Definition: json.hpp:19940
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:21467
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:18935
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true)
Definition: json.hpp:22517
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:22616
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:22602
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:21740
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:19479
const_reference operator[](T *key) const
Definition: json.hpp:20294
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:18496
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:21660
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21492
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:22067
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:22269
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:18305
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:19963
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:22000
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21293
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:18948
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:20762
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(detail::span_input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
Definition: json.hpp:22525
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:22296
value_type & reference
the type of an element reference
Definition: json.hpp:18350
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:20702
detail::out_of_range out_of_range
Definition: json.hpp:18331
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:20153
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:20115
binary_t & get_binary()
get a binary value
Definition: json.hpp:20034
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19162
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22219
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:21749
basic_json(const JsonRef &ref)
Definition: json.hpp:19272
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22196
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:19361
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19134
reference back()
access the last element
Definition: json.hpp:20488
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:20046
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:22040
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:22288
StringType string_t
a type for a string
Definition: json.hpp:18488
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:21205
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:20135
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:18389
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:20428
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:18480
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:18357
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:19927
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:18355
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19090
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21197
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:18982
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:18365
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:22557
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:20792
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:22489
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:18363
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:22321
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:18492
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21268
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:19401
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:20250
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:22049
std::decay< ValueType >::type value(KeyType &&key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:20396
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:20509
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:20746
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:22305
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:21765
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:22542
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:19437
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:21893
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21499
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:21859
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20069
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19123
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:19430
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:19472
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22212
void swap(object_t &other)
exchanges the values
Definition: json.hpp:21590
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:19486
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20819
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:20303
const_reference front() const
access the first element
Definition: json.hpp:20481
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19423
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:18504
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:18372
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:21959
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:21875
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19276
~basic_json() noexcept
destructor
Definition: json.hpp:19382
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:20778
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22242
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19344
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:21918
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:20810
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22261
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:21756
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:21396
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:21868
json_value m_value
the value of the current element
Definition: json.hpp:22179
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:21635
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:21925
void swap(array_t &other)
exchanges the values
Definition: json.hpp:21575
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19101
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:18471
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:19974
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:20173
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:21416
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:19914
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:22644
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:23101
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19674
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:21447
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:18484
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:19951
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:21900
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:20327
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:20579
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:19451
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:21546
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:21943
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:22395
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19507
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) const _reference operator[](const
access specified element via JSON Pointer
Definition: json.hpp:22622
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19142
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:21389
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:22449
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:20191
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:21909
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:22312
std::decay< ValueType >::type value(const char *key, ValueType &&default_value) const
Definition: json.hpp:20379
string_t value(KeyType &&key, const char *default_value) const
access specified object element with default value
Definition: json.hpp:20419
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:21620
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:18368
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:18374
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:22434
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:21774
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22253
string_t value(const char *key, const char *default_value) const
Definition: json.hpp:20384
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:20802
void swap(string_t &other)
exchanges the values
Definition: json.hpp:21605
const_reference back() const
access the last element
Definition: json.hpp:20497
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:21781
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:19112
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:19500
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:19493
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:21350
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) ValueType value(const
access specified object element via JSON Pointer with default value
Definition: json.hpp:20449
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:21934
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:22143
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:18352
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:22337
reference operator[](T *key)
Definition: json.hpp:20288
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:19458
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:21981
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:21284
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:19465
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:18313
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22205
detail::value_t value_t
Definition: json.hpp:18303
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:20695
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22235
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:20272
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:18512
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:18956
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:22504
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference operator[](const
Definition: json.hpp:22608
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:20237
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:18360
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:18508
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:18307
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:21237
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference at(const
Definition: json.hpp:22636
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: json.hpp:22014
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:20826
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:22380
string_t value(const typename object_t::key_type &key, const char *default_value) const
access specified object element with default value
Definition: json.hpp:20368
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:18968
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:18500
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:20732
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:21260
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:21884
std::decay< ValueType >::type value(const KeyType &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:20347
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:22128
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:19034
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:20092
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:21369
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:18370
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19514
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:19444
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:21563
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:22280
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:19873
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:21318
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22228
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:21229
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:20684
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19149
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:18381
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19685
an internal type for a backed binary type
Definition: json.hpp:5274
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5295
BinaryType container_type
Definition: json.hpp:5276
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5285
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5290
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5314
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5343
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5280
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5302
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5336
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5321
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5329
std::uint64_t subtype_type
Definition: json.hpp:5277
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5308
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:8536
binary_reader & operator=(const binary_reader &)=delete
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:8552
binary_reader & operator=(binary_reader &&)=default
binary_reader(const binary_reader &)=delete
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:8573
binary_reader(binary_reader &&)=default
serialization to CBOR and MessagePack values
Definition: json.hpp:14060
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:14759
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:15844
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:14071
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:15822
void write_bson(const BasicJsonType &j)
Definition: json.hpp:14080
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:14109
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:15815
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:14433
general exception of the basic_json class
Definition: json.hpp:3874
const int id
the id of the exception
Definition: json.hpp:3883
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:3894
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:3900
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:3889
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:3877
Definition: json.hpp:5547
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
char char_type
Definition: json.hpp:5549
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5563
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:5607
~input_stream_adapter()
Definition: json.hpp:5588
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(const input_stream_adapter &)=delete
char char_type
Definition: json.hpp:5586
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::char_traits< char >::int_type get_character()
Definition: json.hpp:5617
input_stream_adapter(std::istream &i)
Definition: json.hpp:5598
exception indicating errors with iterators
Definition: json.hpp:4025
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4028
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12093
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:12556
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12686
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:12547
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:12283
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12120
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:12470
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:12697
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12202
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:12129
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:12322
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:12609
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:12124
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12227
pointer operator->() const
dereference the iterator
Definition: json.hpp:12366
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12192
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12217
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:12789
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:12664
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:12675
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:12764
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:12511
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:12600
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12118
reference value() const
return the value of an iterator
Definition: json.hpp:12780
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:12419
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12726
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:12591
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:12408
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12115
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:12459
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12618
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:12655
std::input_iterator_tag iterator_category
Definition: json.hpp:4634
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:4635
iteration_proxy_value(IteratorType it) noexcept
Definition: json.hpp:4650
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:4676
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:4718
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:4661
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:4655
std::ptrdiff_t difference_type
Definition: json.hpp:4630
const string_type & key() const
return key of the iterator
Definition: json.hpp:4682
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:4670
proxy class for the items() function
Definition: json.hpp:4726
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4737
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4743
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4733
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:5641
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5643
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:5647
Definition: json.hpp:13819
json_ref(json_ref &&) noexcept=default
value_type const & operator*() const
Definition: json.hpp:13858
BasicJsonType value_type
Definition: json.hpp:13821
json_ref(Args &&... args)
Definition: json.hpp:13838
json_ref(const value_type &value)
Definition: json.hpp:13827
value_type const * operator->() const
Definition: json.hpp:13863
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:13831
json_ref(value_type &&value)
Definition: json.hpp:13823
value_type moved_or_copied() const
Definition: json.hpp:13849
a template for a reverse iterator class
Definition: json.hpp:12831
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:12840
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:12837
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12883
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12871
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:12835
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:12844
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12895
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:12859
std::ptrdiff_t difference_type
Definition: json.hpp:12833
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:12889
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:12877
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:12847
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:12901
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:12865
reference value() const
return the value of an iterator
Definition: json.hpp:12908
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:12853
Definition: json.hpp:6634
bool end_array()
Definition: json.hpp:6697
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:6677
typename BasicJsonType::string_t string_t
Definition: json.hpp:6639
bool binary(binary_t &)
Definition: json.hpp:6672
bool boolean(bool)
Definition: json.hpp:6647
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6636
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6638
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6640
bool key(string_t &)
Definition: json.hpp:6682
bool end_object()
Definition: json.hpp:6687
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:6692
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:6702
bool number_integer(number_integer_t)
Definition: json.hpp:6652
bool string(string_t &)
Definition: json.hpp:6667
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:6657
bool null()
Definition: json.hpp:6642
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6637
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:6662
typename BasicJsonType::string_t string_t
Definition: json.hpp:6332
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
bool start_object(std::size_t len)
Definition: json.hpp:6394
bool key(string_t &val)
Definition: json.hpp:6412
constexpr bool is_errored() const
Definition: json.hpp:6527
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6330
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6329
bool null()
Definition: json.hpp:6352
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6334
bool start_array(std::size_t len)
Definition: json.hpp:6465
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6333
bool binary(binary_t &val)
Definition: json.hpp:6388
bool number_integer(number_integer_t val)
Definition: json.hpp:6364
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6331
bool end_array()
Definition: json.hpp:6482
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6335
bool boolean(bool val)
Definition: json.hpp:6358
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6370
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool string(string_t &val)
Definition: json.hpp:6382
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6376
bool end_object()
Definition: json.hpp:6429
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6515
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6337
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6153
bool start_array(std::size_t len)
Definition: json.hpp:6245
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6159
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6195
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6155
bool boolean(bool val)
Definition: json.hpp:6183
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6265
bool string(string_t &val)
Definition: json.hpp:6207
bool end_object()
Definition: json.hpp:6238
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6156
bool start_object(std::size_t len)
Definition: json.hpp:6219
bool null()
Definition: json.hpp:6177
bool binary(binary_t &val)
Definition: json.hpp:6213
constexpr bool is_errored() const
Definition: json.hpp:6277
bool key(string_t &val)
Definition: json.hpp:6231
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6157
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6201
bool end_array()
Definition: json.hpp:6257
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6166
typename BasicJsonType::string_t string_t
Definition: json.hpp:6158
bool number_integer(number_integer_t val)
Definition: json.hpp:6189
Definition: json.hpp:6741
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:6768
token_type
token types for the parser
Definition: json.hpp:6745
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition: json.hpp:6818
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8136
token_type scan()
Definition: json.hpp:8215
void skip_whitespace()
Definition: json.hpp:8206
lexer & operator=(lexer &&)=default
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8192
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:6829
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8146
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8118
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:6827
lexer & operator=(lexer &)=delete
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8124
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8130
std::string get_token_string() const
Definition: json.hpp:8154
lexer(lexer &&)=default
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8179
exception indicating other library errors
Definition: json.hpp:4077
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4080
exception indicating access out of the defined range
Definition: json.hpp:4060
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4063
Definition: json.hpp:14019
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14026
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14022
output_adapter(StringType &s)
Definition: json.hpp:14030
output adapter for output streams
Definition: json.hpp:13971
void write_character(CharType c) override
Definition: json.hpp:13977
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:13973
output adapter for basic_string
Definition: json.hpp:13996
void write_character(CharType c) override
Definition: json.hpp:14002
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:13998
output adapter for byte vectors
Definition: json.hpp:13946
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:13948
void write_character(CharType c) override
Definition: json.hpp:13952
exception indicating a parse error
Definition: json.hpp:3972
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:3984
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:3992
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4009
syntax analysis
Definition: json.hpp:11446
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:11546
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:11456
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:11538
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:11478
Definition: json.hpp:11920
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:11970
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:11982
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:11955
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12014
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:11949
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11965
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:11988
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:11937
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11960
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11977
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:11995
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:11943
constexpr difference_type get_value() const noexcept
Definition: json.hpp:11931
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12001
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12008
Definition: json.hpp:17023
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:17955
const std::lconv * loc
the locale
Definition: json.hpp:17940
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:17937
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition: json.hpp:17944
std::uint8_t state
Definition: json.hpp:17365
std::size_t bytes
Definition: json.hpp:17366
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:17942
serializer & operator=(const serializer &)=delete
std::size_t undumped_chars
Definition: json.hpp:17370
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:17078
const char indent_char
the indentation character
Definition: json.hpp:17950
std::size_t bytes_after_last_accept
Definition: json.hpp:17369
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:17947
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:17363
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17038
serializer(const serializer &)=delete
string_t indent_string
the indentation string
Definition: json.hpp:17952
Definition: json.hpp:5965
contiguous_bytes_input_adapter && get()
Definition: json.hpp:5983
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:5973
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5980
exception indicating executing a member function with a wrong type
Definition: json.hpp:4043
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4046
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5806
char char_type
Definition: json.hpp:5801
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:5803
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:12950
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:13034
void pop_back()
remove last reference token
Definition: json.hpp:13062
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:13041
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13048
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13100
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13019
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13086
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:12972
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13001
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:13026
friend class json_pointer
Definition: json.hpp:12956
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12982
friend bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:13790
const string_t & back() const
return last reference token
Definition: json.hpp:13074
friend bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13797
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13011
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:12976
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13093
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:4788
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2508
#define JSON_HEDLEY_CONST
Definition: json.hpp:1687
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:971
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1317
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2471
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:52
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1582
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1475
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2438
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:1916
#define JSON_CATCH(exception)
Definition: json.hpp:2437
#define JSON_ASSERT(x)
Definition: json.hpp:2464
#define JSON_THROW(exception)
Definition: json.hpp:2435
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:50
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2517
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1583
#define JSON_TRY
Definition: json.hpp:2436
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2417
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:51
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:972
#define JSON_EXPLICIT
Definition: json.hpp:2729
#define JSON_HEDLEY_PURE
Definition: json.hpp:1656
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:16698
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:16850
Target reinterpret_bits(const Source source)
Definition: json.hpp:15918
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:16059
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:16362
constexpr int kGamma
Definition: json.hpp:16182
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:16416
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:16798
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:16457
constexpr int kAlpha
Definition: json.hpp:16181
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:16198
detail namespace with internal helper functions
Definition: json.hpp:109
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:2862
typename T::reference reference_t
Definition: json.hpp:3225
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:3788
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:165
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3310
typename T::key_compare detect_key_compare
Definition: json.hpp:3294
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3234
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:3785
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5054
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition: json.hpp:3406
value_t
the JSON type enumeration
Definition: json.hpp:139
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4136
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:2966
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:8405
typename T::pointer pointer_t
Definition: json.hpp:3222
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8378
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:3773
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:11437
typename T::difference_type difference_type_t
Definition: json.hpp:3219
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:2294
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:4621
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4290
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:2904
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8390
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8362
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8382
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8366
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:16935
typename std::conditional< is_key_type_comparable< BasicJsonType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, typename BasicJsonType::object_t::key_type >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, typename BasicJsonType::object_comparator_t >::value) &&!is_json_iterator_of< BasicJsonType, KeyType >::value &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.hpp:3670
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5177
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3403
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:2307
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:2848
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:3770
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:8508
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
parse_event_t
Definition: json.hpp:11420
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition: json.hpp:17015
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8386
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5881
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.hpp:3682
typename T::key_type key_type_t
Definition: json.hpp:3213
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5380
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5398
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2777
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:2950
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8370
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:2303
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:2300
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:8397
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition: json.hpp:4479
void concat_into(OutStringType &)
Definition: json.hpp:3766
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4150
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2758
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:2288
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:3791
typename make_void< Ts... >::type void_t
Definition: json.hpp:2250
OutStringType concat(Args &&... args)
Definition: json.hpp:3850
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:2958
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:13941
typename T::mapped_type mapped_type_t
Definition: json.hpp:3210
input_format_t
the supported input formats
Definition: json.hpp:5535
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5171
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4473
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3237
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3673
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition: json.hpp:4373
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:3782
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:5938
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3650
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8358
typename is_comparable< typename BasicJsonType::object_comparator_t, const key_type_t< typename BasicJsonType::object_t > &, KeyType >::type is_key_type_comparable
Definition: json.hpp:3647
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4752
typename T::iterator_category iterator_category_t
Definition: json.hpp:3228
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8374
std::size_t concat_length()
Definition: json.hpp:3735
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:3779
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:3776
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:8400
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:4538
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8393
T conditional_static_cast(U value)
Definition: json.hpp:3704
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3231
typename T::value_type value_type_t
Definition: json.hpp:3216
namespace for Niels Lohmann
Definition: json.hpp:107
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:23133
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin)
bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.hpp:13797
bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.hpp:13790
Definition: json.hpp:4772
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:23179
default JSONSerializer template argument
Definition: json.hpp:5227
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:5231
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5241
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5251
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3304
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3306
typename BasicJsonType::object_t object_t
Definition: json.hpp:3303
Definition: json.hpp:3318
Definition: json.hpp:3317
Definition: json.hpp:2275
Default type
Definition: json.hpp:2277
std::false_type value_t
Definition: json.hpp:2276
Definition: json.hpp:16046
diyfp plus
Definition: json.hpp:16049
diyfp w
Definition: json.hpp:16047
diyfp minus
Definition: json.hpp:16048
std::uint64_t f
Definition: json.hpp:16186
int k
Definition: json.hpp:16188
int e
Definition: json.hpp:16187
Definition: json.hpp:15928
static constexpr int kPrecision
Definition: json.hpp:15929
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16017
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:16034
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:15952
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:15934
int e
Definition: json.hpp:15932
std::uint64_t f
Definition: json.hpp:15931
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:15940
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:4966
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:4995
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:4979
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:4954
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:4944
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:4883
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:4892
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:4837
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:4905
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:4931
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:4918
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5024
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5014
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5035
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:4859
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:4870
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:4850
Definition: json.hpp:4568
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:4570
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3256
Definition: json.hpp:3241
Definition: json.hpp:3297
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3271
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3286
Definition: json.hpp:3281
Definition: json.hpp:4106
Definition: json.hpp:2890
T value_type
Definition: json.hpp:2891
static constexpr std::size_t size() noexcept
Definition: json.hpp:2892
an iterator value
Definition: json.hpp:12035
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12041
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12039
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:12037
Definition: json.hpp:3177
Definition: json.hpp:3634
static constexpr auto value
Definition: json.hpp:3478
Definition: json.hpp:3604
Definition: json.hpp:3413
static constexpr auto value
Definition: json.hpp:3492
ConstructibleStringType laundered_type
Definition: json.hpp:3489
Definition: json.hpp:3350
Definition: json.hpp:2291
Definition: json.hpp:3249
static constexpr bool value
Definition: json.hpp:3250
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:5858
Definition: json.hpp:3366
Definition: json.hpp:3613
Definition: json.hpp:3200
Definition: json.hpp:3692
char x[2]
Definition: json.hpp:3693
Definition: json.hpp:3688
@ value
Definition: json.hpp:3699
char one
Definition: json.hpp:3689
static one test(decltype(&C::capacity))
Definition: json.hpp:3385
static constexpr bool value
Definition: json.hpp:3399
Definition: json.hpp:8409
static constexpr bool value
Definition: json.hpp:8422
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5869
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5846
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:5849
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:5847
IteratorType iterator_type
Definition: json.hpp:5845
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3050
Definition: json.hpp:3038
Definition: json.hpp:3019
Definition: json.hpp:2247
void type
Definition: json.hpp:2248
Definition: json.hpp:3324
Definition: json.hpp:2261
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:13927
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition: json.hpp:2812
std::size_t lines_read
the number of lines read
Definition: json.hpp:2818
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:2816
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:2814
Definition: json.hpp:2974
Definition: json.hpp:2973
Definition: json.hpp:2979
static constexpr T value
Definition: json.hpp:2980
Definition: json.hpp:5197
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:5199
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:2931
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5738
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5680
SAX interface.
Definition: json.hpp:6022
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string value was read
virtual bool null()=0
a null value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6023
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6027
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6024
virtual bool binary(binary_t &val)=0
a binary value was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6025
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.hpp:6026
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:17987
T & at(const Key &key)
Definition: json.hpp:18034
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:17990
T mapped_type
Definition: json.hpp:17989
const T & at(const Key &key) const
Definition: json.hpp:18047
iterator find(const Key &key)
Definition: json.hpp:18144
iterator erase(iterator pos)
Definition: json.hpp:18079
void insert(InputIt first, InputIt last)
Definition: json.hpp:18191
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:18168
const_iterator find(const Key &key) const
Definition: json.hpp:18156
Key key_type
Definition: json.hpp:17988
size_type erase(const Key &key)
Definition: json.hpp:18060
T & operator[](const Key &key)
Definition: json.hpp:18024
iterator erase(iterator first, iterator last)
Definition: json.hpp:18084
typename Container::const_iterator const_iterator
Definition: json.hpp:17992
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:18188
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18006
std::equal_to< Key > key_compare
Definition: json.hpp:17998
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18004
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:18173
typename Container::size_type size_type
Definition: json.hpp:17993
typename Container::value_type value_type
Definition: json.hpp:17994
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18008
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18003
size_type count(const Key &key) const
Definition: json.hpp:18132
typename Container::iterator iterator
Definition: json.hpp:17991
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18011
const T & operator[](const Key &key) const
Definition: json.hpp:18029
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:23152
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:23166